just wondering if someone can provide a solution

Go To Last Post
50 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hi guys, I am creating a program on the SAMA5D44, yes I know this is not really the place to be asking such questions but I've been waiting on Microchip to et back to me.

 

The problem is that when I run the program I have three global structs * pointer that are all located at 0 address????

 

What do you guys think ?

Last Edited: Thu. Aug 16, 2018 - 10:14 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

A pointer that has the value NULL (which in the normal universe, means the value zero, 0x00, 0, etc...) has not been initialized to have the address of the variable that the pointer should be referring to.  Or, if the pointer is to a function, then this pointer has not been initialized with the address of the function that the main code will be calling when this function pointer is invoked (not sure of the proper CompSci term). 

  So, uh, that's a lot of words that may not make any sense.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hi, I mean the pointer location I always NULL, not the address pointed to.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

How does this relate to the sam device? Apart from it being the execution platform? It sounds more like a compiler or language issue. Can you give us a bit more context?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I'm using "arm-none-eabi" compiler but I have also tried "cygwin64"

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

What do you guys think ?

With that description, you'll probably be waiting a long time to hear from Microchip  

When in the dark remember-the future looks brighter than ever.   I look forward to being able to predict the future!

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 1

Fianawarrior wrote:

What do you guys think ?

 

You didn't set them to something else.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

nope

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

All the pointer are located in the same address on memory.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Try a linter though would be quicker to enable strict checking via a compiler switch.

 

"Dare to be naïve." - Buckminster Fuller

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Did you mean Linker gchapman?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

lint for C or C++ (well, some other computer languages have a linter)

 

"Dare to be naïve." - Buckminster Fuller

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I'd suggest the problem is somewhere between the keyboard and the chair. Microchip/Atmel don't write the compiler - ARM themselves probably have more significant input to it. Can you post a minimal piece of code that demonstrates the problem?

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Okay then

 

struct task_ctrl_obj {

	unsigned char * stack_ptr;				// Task Stack Pointer saved by the contest switch
	unsigned char * stack_allocation;		// Pointer for De-allocation of Stack

	int  delay_counter;						// Task delay counter if zero then task is not waiting otherwise
											// we can assume that the task is waiting on a delay request

	unsigned char * mpu_base_mem_addr;
	unsigned char ergonRegion;
	bool mpu_protection;

	char name[30];

	unsigned char	default_priority;		// Default Task Priority	0 - 63
	unsigned char	delta_priority;			// Task Run-time Priority	0 - 63

	unsigned char   total_futexs_held;		// Used to manage the priority inheritance
	unsigned char	ceiling_priority;		// Futex Ceiling priority
	bool			sem_rw_type;

	unsigned char	task_status;			// Task Status, i.e., READY, WAITING, DORMANT, DELAYED
	unsigned char	internal_ctrl;			// Ctrl Status, i.e. TIMEOUT, SEMACK, etc
};

volatile struct task_ctrl_obj  * OSTCBHighRdy;
volatile struct task_ctrl_obj  * core_executing_task;


volatile struct task_ctrl_obj * test1;
volatile struct task_ctrl_obj * test2;
volatile struct task_ctrl_obj * test3;


static struct task_ctrl_obj * api_program(void(*task)(void), char const * name, void * variable_pass, unsigned int mpu_mem, unsigned char priority, unsigned char ceiling ){
	//api_system_gateway();

	if(priority > 63){
		return(0);
	}

	struct task_ctrl_obj * tcb;

	tcb = malloc(sizeof(struct task_ctrl_obj));			// Allocate Memory for the Task Ctrl Block, used by the Kernel to manage the Task


	if(tcb == NULL){
		printf("\n\tError Allocating service TCB\n\r");
		return(NULL);
	}

		unsigned int stack;


		tcb->mpu_base_mem_addr = malloc(mpu_mem * sizeof(int));
		tcb->stack_allocation = (unsigned char *)tcb->mpu_base_mem_addr;


		stack = mpu_mem * sizeof(int);


		if(tcb->mpu_base_mem_addr == NULL){
			printf("\n\tError Allocating stack TCB\n\r");
			free(tcb);
			return(NULL);
		}

		unsigned int * cpu_core_stack = (unsigned int *)(stack + tcb->mpu_base_mem_addr);												// PointStack to the end of the memory structure, Stack grows upwards
		cpu_core_stack = (unsigned int *)((unsigned int)(cpu_core_stack) & 0xFFFFFFF8u);

		//tcb->task_status = DORMANT;											// Initial State of all Tasks is DORMANT

	/*
	 *	Prepare Task context
	 */

	/*
	 * Setup tcb priority
	 */
	tcb->delta_priority   = priority;									// Set Task Priority
	tcb->ceiling_priority = ceiling;
	tcb->default_priority = priority;									// Set Base Priority, used by the Priority inversion protocol



	/*
	 * Setup general purpose registers
	 */
     * cpu_core_stack-- = (unsigned int) task;											   /* R15/PC                                                    */
     * cpu_core_stack-- = (unsigned int) task;		                                  	   /* SR: Supervisor mode                                       */
     * cpu_core_stack-- = (unsigned int) 0x00000000;                                       /* R0                                                        */
     * cpu_core_stack-- = (unsigned int) 0x00000000;                                       /* R1                                                        */
     * cpu_core_stack-- = (unsigned int) 0x00000000;                                       /* R2				                                           */
     * cpu_core_stack-- = (unsigned int) 0x00000000;		                               /* R3							    		                   */
     * cpu_core_stack-- = (unsigned int) 0x00000000;                                       /* R4                                                        */
     * cpu_core_stack-- = (unsigned int) 0x00000000;									   /* R5				                                           */
     * cpu_core_stack-- = (unsigned int) 0x00000000;                                       /* R6                                                        */
     * cpu_core_stack-- = (unsigned int) 0x00000000;                                       /* R7                                                        */
     * cpu_core_stack-- = (unsigned int) 0x00000000;                                       /* R8                                                        */
     * cpu_core_stack-- = (unsigned int) 0x00000000;                                       /* R9                                                        */
     * cpu_core_stack-- = (unsigned int) 0x00000000;                                       /* R10                                                       */
     * cpu_core_stack-- = (unsigned int) 0x00000000;                                       /* R11                                                       */
     * cpu_core_stack-- = (unsigned int) variable_pass;                                    /* R12 ARGUMENT PASS                                         */


	#define  OS_CPU_ARM_BIT_CPSR_MODE_SUPERVISOR 0x13u
	#define  OS_CPU_ARM_BIT_CPSR_T (1u << 5u)

     // Stup Status registers
     * cpu_core_stack-- = (unsigned int)(0x00000100 | OS_CPU_ARM_BIT_CPSR_MODE_SUPERVISOR);



     {	/*
     	 *	Setup Floating Point registers
     	 **/
    	 *cpu_core_stack-- = 0x00000000;	 	/* Initialise Floating point status & control register  */

    	 for (int i = 0; i < 32; i++)
    		 * cpu_core_stack-- = 0x00000000;	/* Initialise general-purpose Floating point registers  */

    	 * cpu_core_stack = 0x40000000;  	 	/* Initialise Floating-Point Exception Register (Enable)*/
     }

//	internal_kernel_insert_task(tcb);											// insert task ctrl block unto Kernel Schedular
	tcb->stack_ptr = (unsigned char *)cpu_core_stack;													// Store Stack pointer unto the task ctrl block
	return(tcb);														// Return Handle to the newly Created Task
}



static void task1 (void){

	printf("Task 1 Running");
	while (1);
}

static void task2 (void){

	printf("Task 2 Running");
	while (1);
}

static void task3 (void){

	printf("Task 3 Running");
	while (1);
}

/**
 *  \brief getting-started Application entry point.
 *
 *  \return Unused (ANSI-C compatibility).
 */
int main(void)
{


	console_example_info("Getting Started Example");


	test1 = api_program(task1,"test" ,NULL ,4096 ,11 ,11);
	test2 = api_program(task2,"test" ,NULL ,4096 ,10 ,10);
	test3 = api_program(task3,"test" ,NULL ,4096 ,10 ,10);

	printf("\n\r\n\rtest1 %x", test1);
	printf("\n\rtest2 %x", test2);
	printf("\n\rtest3 %x", test3);

	OSTCBHighRdy = test1;
	run();
}

It will run task3 because it is was the last to load and overwrite the previous pointer because they are all located at address 0.

 

 

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

that doesn't have any includes so try that through a DIY at

Gimpel Home Page

Gimpel On-Line Demos

http://www.gimpel-online.com/OnlineTesting.html

 

If one of your IDEs is Microsoft Visual Studio then there's a built-in C and C++ linter (/analyze)

 

"Dare to be naïve." - Buckminster Fuller

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

So you think test1, test2, and test3 all are at zero?  Based on what evidence?  It looks fine to me:

00008181 t task1
00008185 t task2
00008189 t task3
000116bc B test1
000116c8 B test2
000116cc B test3

 

What does run() do?  I don't see tcbs getting enqueued on any list or put an an array, so if run() is a scheduler, I don't see how it's going to figure out which tasks have been created to step through them or anything.

 

Do you have a linker problem?  unlinked, or partially linked (if that's a thing) can show zero as the value of to-be-resolved symbols.

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 1

If you want to print a pointer address should you not use:

 

printf("\n\r\n\rtest1 %p", test1);
printf("\n\rtest2 %p", test2);
printf("\n\rtest3 %p", test3);

I use http://www.cplusplus.com/referen... as my reference.

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

%p gives you the value of a pointer - ie, the address that it points to.

 

If you wanted the addresses at which the pointers themselves are stored, that would be:

printf("\n\r\n\rtest1 %p", &test1);
printf("\n\rtest2 %p",     &test2);
printf("\n\rtest3 %p",     &test3);

I use http://www.cplusplus.com/referen... as my reference.

An excellent reference!

It's on the list: http://blog.antronics.co.uk/2011...

 

Top Tips:

  1. How to properly post source code - see: https://www.avrfreaks.net/comment... - also how to properly include images/pictures
  2. "Garbage" characters on a serial terminal are (almost?) invariably due to wrong baud rate - see: https://learn.sparkfun.com/tutorials/serial-communication
  3. Wrong baud rate is usually due to not running at the speed you thought; check by blinking a LED to see if you get the speed you expected
  4. Difference between a crystal, and a crystal oscillatorhttps://www.avrfreaks.net/comment...
  5. When your question is resolved, mark the solution: https://www.avrfreaks.net/comment...
  6. Beginner's "Getting Started" tips: https://www.avrfreaks.net/comment...
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I modified the code a wee bit so it could build with MSVC:

#include <stdlib.h>
#include <stdio.h>

struct task_ctrl_obj {

	unsigned char * stack_ptr;				// Task Stack Pointer saved by the contest switch
	unsigned char * stack_allocation;		// Pointer for De-allocation of Stack

	int  delay_counter;						// Task delay counter if zero then task is not waiting otherwise
											// we can assume that the task is waiting on a delay request

	unsigned char * mpu_base_mem_addr;
	unsigned char ergonRegion;
	bool mpu_protection;

	char name[30];

	unsigned char	default_priority;		// Default Task Priority	0 - 63
	unsigned char	delta_priority;			// Task Run-time Priority	0 - 63

	unsigned char   total_futexs_held;		// Used to manage the priority inheritance
	unsigned char	ceiling_priority;		// Futex Ceiling priority
	bool			sem_rw_type;

	unsigned char	task_status;			// Task Status, i.e., READY, WAITING, DORMANT, DELAYED
	unsigned char	internal_ctrl;			// Ctrl Status, i.e. TIMEOUT, SEMACK, etc
};

volatile struct task_ctrl_obj  * OSTCBHighRdy;
volatile struct task_ctrl_obj  * core_executing_task;


volatile struct task_ctrl_obj * test1;
volatile struct task_ctrl_obj * test2;
volatile struct task_ctrl_obj * test3;


static struct task_ctrl_obj * api_program(void(*task)(void), char const * name, void * variable_pass, unsigned int mpu_mem, unsigned char priority, unsigned char ceiling ){
	//api_system_gateway();

	if(priority > 63){
		return(0);
	}

	struct task_ctrl_obj * tcb;

	tcb = (struct task_ctrl_obj *)malloc(sizeof(struct task_ctrl_obj));			// Allocate Memory for the Task Ctrl Block, used by the Kernel to manage the Task


	if(tcb == NULL){
		printf("\n\tError Allocating service TCB\n\r");
		return(NULL);
	}

		unsigned int stack;


		tcb->mpu_base_mem_addr = (unsigned char *)malloc(mpu_mem * sizeof(int));
		tcb->stack_allocation = (unsigned char *)tcb->mpu_base_mem_addr;
        printf("stack base: %08X\n", tcb->stack_allocation);
        printf("ends at: %08X\n", tcb->mpu_base_mem_addr + (mpu_mem * sizeof(int)));


		stack = mpu_mem * sizeof(int);


		if(tcb->mpu_base_mem_addr == NULL){
			printf("\n\tError Allocating stack TCB\n\r");
			free(tcb);
			return(NULL);
		}

		unsigned int * cpu_core_stack = (unsigned int *)(stack + tcb->mpu_base_mem_addr);												// PointStack to the end of the memory structure, Stack grows upwards
		cpu_core_stack = (unsigned int *)((unsigned int)(cpu_core_stack) & 0xFFFFFFF8u);
        printf("top of cpu core @ %08X\n", cpu_core_stack);

		//tcb->task_status = DORMANT;											// Initial State of all Tasks is DORMANT

	/*
	 *	Prepare Task context
	 */

	/*
	 * Setup tcb priority
	 */
	tcb->delta_priority   = priority;									// Set Task Priority
	tcb->ceiling_priority = ceiling;
	tcb->default_priority = priority;									// Set Base Priority, used by the Priority inversion protocol



	/*
	 * Setup general purpose registers
	 */
     * cpu_core_stack-- = (unsigned int) task;											   /* R15/PC                                                    */
     * cpu_core_stack-- = (unsigned int) task;		                                  	   /* SR: Supervisor mode                                       */
     * cpu_core_stack-- = (unsigned int) 0x00000000;                                       /* R0                                                        */
     * cpu_core_stack-- = (unsigned int) 0x00000000;                                       /* R1                                                        */
     * cpu_core_stack-- = (unsigned int) 0x00000000;                                       /* R2				                                           */
     * cpu_core_stack-- = (unsigned int) 0x00000000;		                               /* R3							    		                   */
     * cpu_core_stack-- = (unsigned int) 0x00000000;                                       /* R4                                                        */
     * cpu_core_stack-- = (unsigned int) 0x00000000;									   /* R5				                                           */
     * cpu_core_stack-- = (unsigned int) 0x00000000;                                       /* R6                                                        */
     * cpu_core_stack-- = (unsigned int) 0x00000000;                                       /* R7                                                        */
     * cpu_core_stack-- = (unsigned int) 0x00000000;                                       /* R8                                                        */
     * cpu_core_stack-- = (unsigned int) 0x00000000;                                       /* R9                                                        */
     * cpu_core_stack-- = (unsigned int) 0x00000000;                                       /* R10                                                       */
     * cpu_core_stack-- = (unsigned int) 0x00000000;                                       /* R11                                                       */
     * cpu_core_stack-- = (unsigned int) variable_pass;                                    /* R12 ARGUMENT PASS                                         */


	#define  OS_CPU_ARM_BIT_CPSR_MODE_SUPERVISOR 0x13u
	#define  OS_CPU_ARM_BIT_CPSR_T (1u << 5u)

     // Stup Status registers
     * cpu_core_stack-- = (unsigned int)(0x00000100 | OS_CPU_ARM_BIT_CPSR_MODE_SUPERVISOR);
     printf("after reg stack SP = %08X\n", cpu_core_stack);



     {	/*
     	 *	Setup Floating Point registers
     	 **/
    	 *cpu_core_stack-- = 0x00000000;	 	/* Initialise Floating point status & control register  */

    	 for (int i = 0; i < 32; i++)
    		 * cpu_core_stack-- = 0x00000000;	/* Initialise general-purpose Floating point registers  */

    	 * cpu_core_stack = 0x40000000;  	 	/* Initialise Floating-Point Exception Register (Enable)*/
     }
     printf("after FP reg stack = %08X\n", cpu_core_stack);

//	internal_kernel_insert_task(tcb);											// insert task ctrl block unto Kernel Schedular
	tcb->stack_ptr = (unsigned char *)cpu_core_stack;													// Store Stack pointer unto the task ctrl block
    printf("return TCB @ %08X\n", &tcb);
	return(tcb);														// Return Handle to the newly Created Task
}



static void task1 (void){

	printf("Task 1 Running");
	while (1);
}

static void task2 (void){

	printf("Task 2 Running");
	while (1);
}

static void task3 (void){

	printf("Task 3 Running");
	while (1);
}

/**
 *  \brief getting-started Application entry point.
 *
 *  \return Unused (ANSI-C compatibility).
 */
int main(void)
{

    // removed - this function not present
	//console_example_info("Getting Started Example");


    printf("call api_prog for test1\n");
	test1 = api_program(task1,"test" ,NULL ,4096 ,11 ,11);
    printf("test1 = %08X\n", test1);

    printf("call api_prog for test2\n");
	test2 = api_program(task2,"test" ,NULL ,4096 ,10 ,10);
    printf("test2 = %08X\n", test2);

    printf("call api_prog for test3\n");
	test3 = api_program(task3,"test" ,NULL ,4096 ,10 ,10);
    printf("test3 = %08X\n", test3);

	printf("\n\r\n\rtest1 %x", test1);
	printf("\n\rtest2 %x", test2);
	printf("\n\rtest3 %x", test3);

	OSTCBHighRdy = test1;
    // removed - this is not present
	// run();
}

When I run that in the debugger I see:

call api_prog for test1
stack base: 001C5E28
ends at: 001C9E28
top of cpu core @ 001C9E28
after reg stack SP = 001C9DE8
after FP reg stack = 001C9D64
return TCB @ 0036FCC8
test1 = 001C1AD0
call api_prog for test2
stack base: 00370068
ends at: 00374068
top of cpu core @ 00374068
after reg stack SP = 00374028
after FP reg stack = 00373FA4
return TCB @ 0036FCC8
test2 = 001C1B48
call api_prog for test3
stack base: 003740A8
ends at: 003780A8
top of cpu core @ 003780A8
after reg stack SP = 00378068
after FP reg stack = 00377FE4
return TCB @ 0036FCC8
test3 = 001C1BC0


test1 1c1ad0
test2 1c1b48
test3 1c1bc0

I don't see much wrong in that?

 

BTW the kind of point I'm making here is that you don't have to squirt this into an embedded ARM chip to see it in action - works just as well for me built for an i5. In fact the advantage I have is that I can not only pepper it with printf()s and see instant results but I can run it in the Visual Studio debugger and see everything going on.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

PS and yes there is a bug in the above. My:

    printf("return TCB @ %08X\n", &tcb);

had a bit more & than I was planning !

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Fianawarrior wrote:
yes I know this is not really the place to be asking such questions
Fianawarrior wrote:
What do you guys think ?

Use the forum for ARM chips?  simply take the drop-down from where you posted and find the right spot.

 

 

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

Last Edited: Thu. Aug 16, 2018 - 01:23 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Actually, as Cliff has already noted, it looks like it is just a General programming question - nothing specifically to do with ARM anyhow.

 

The stupid thing is the forum structure which buries General programming under AVR.

 

Similarly General electronics.

 

angry

 

but I may just have mentioned this before ...

Top Tips:

  1. How to properly post source code - see: https://www.avrfreaks.net/comment... - also how to properly include images/pictures
  2. "Garbage" characters on a serial terminal are (almost?) invariably due to wrong baud rate - see: https://learn.sparkfun.com/tutorials/serial-communication
  3. Wrong baud rate is usually due to not running at the speed you thought; check by blinking a LED to see if you get the speed you expected
  4. Difference between a crystal, and a crystal oscillatorhttps://www.avrfreaks.net/comment...
  5. When your question is resolved, mark the solution: https://www.avrfreaks.net/comment...
  6. Beginner's "Getting Started" tips: https://www.avrfreaks.net/comment...
Last Edited: Thu. Aug 16, 2018 - 01:37 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

awneil wrote:
The stupid thing is the forum structure which buries General programming under AVR.

No, it doesn't.  [well, I won't argue against 'stupid' -- there is no defense against stupid]  Did you look at the bottom line of what I pasted above?  Do you see the "and General Programming (ARM-related)" there?  And isn't OP's question about code produced by some particular toolchain?  Wouldn't that be covered under

  1. Home
  2. » Communities
  3. » Atmel SMART ARM-based MCUs
  4. » Forums
  5. » Tools
  6. » Compilers, Assemblers, Linkers and General Programming (ARM-related)

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Ah - I missed that.

 

But it still seems stupid to have two separate "General " programming sections!

 

That makes no sense - if it's General, it shouldn't be under any specific category!

 

Top Tips:

  1. How to properly post source code - see: https://www.avrfreaks.net/comment... - also how to properly include images/pictures
  2. "Garbage" characters on a serial terminal are (almost?) invariably due to wrong baud rate - see: https://learn.sparkfun.com/tutorials/serial-communication
  3. Wrong baud rate is usually due to not running at the speed you thought; check by blinking a LED to see if you get the speed you expected
  4. Difference between a crystal, and a crystal oscillatorhttps://www.avrfreaks.net/comment...
  5. When your question is resolved, mark the solution: https://www.avrfreaks.net/comment...
  6. Beginner's "Getting Started" tips: https://www.avrfreaks.net/comment...
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

awneil wrote:

Actually, as Cliff has already noted, it looks like it is just a General programming question - nothing specifically to do with ARM anyhow.

OK, I'll bite:  I searched the thread for all references to "general" and saw nothing from Cliff.

 

But if Andy and Moderator Cliff say it is appropriate, then my reporting this thread will fall on deaf ears.

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Ah, OK - he didn't actually say it directly. But it's implied in #19, where he takes the code over to native MSVC

Top Tips:

  1. How to properly post source code - see: https://www.avrfreaks.net/comment... - also how to properly include images/pictures
  2. "Garbage" characters on a serial terminal are (almost?) invariably due to wrong baud rate - see: https://learn.sparkfun.com/tutorials/serial-communication
  3. Wrong baud rate is usually due to not running at the speed you thought; check by blinking a LED to see if you get the speed you expected
  4. Difference between a crystal, and a crystal oscillatorhttps://www.avrfreaks.net/comment...
  5. When your question is resolved, mark the solution: https://www.avrfreaks.net/comment...
  6. Beginner's "Getting Started" tips: https://www.avrfreaks.net/comment...
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

awneil wrote:
Ah, OK - he didn't actually say it directly. But it's implied in #19, where he takes the code over to native MSVC

If a responder chooses to take the code to an entirely different platform for some reason, why does that somehow justify posting the ARM-code situation relating to how a particular toolchain generates code to an unrelated (8-bit?) AVR forum, when there is an appropriately/identically named forum on the same site in the ARM section?

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

You've convinced me - there is no reason for this not to be in the ARM General (sic) Programming section.

 

 

Top Tips:

  1. How to properly post source code - see: https://www.avrfreaks.net/comment... - also how to properly include images/pictures
  2. "Garbage" characters on a serial terminal are (almost?) invariably due to wrong baud rate - see: https://learn.sparkfun.com/tutorials/serial-communication
  3. Wrong baud rate is usually due to not running at the speed you thought; check by blinking a LED to see if you get the speed you expected
  4. Difference between a crystal, and a crystal oscillatorhttps://www.avrfreaks.net/comment...
  5. When your question is resolved, mark the solution: https://www.avrfreaks.net/comment...
  6. Beginner's "Getting Started" tips: https://www.avrfreaks.net/comment...
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I think you'll find it's simply because he's got some "good answers" in the past when posting to AVR (actually AVR32 in fact) whereas "ARM" may be a bit of a desolate wasteland for this kind of question.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

clawson wrote:
I think you'll find it's simply because he's got some "good answers" in the past when posting to AVR (actually AVR32 in fact) whereas "ARM" may be a bit of a desolate wasteland for this kind of question.

Well, yeah -- agree [nearly] 100%.  'Freaks is a great resource.  It isn't my problem that that forum is a wasteland.  I'd speculate without digging that this is not the first instance from this poster.  Poster should put into off-topic, or perhaps a link there to the posting in the proper wasteland and then anyone that might be interested can follow up.

 

Next we'll hear about PIC 99V99 COMP operation in COBOL on Burroughs Medium Systems, perhaps.  "General Programming", right?  And a vast wasteland elsewhere.  CC RM ///

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 1

Yeah, but he's Irish so deserves a bit of slackcheeky

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

theusch wrote:
this is not the first instance from this poster. 

certainly isn't!

 

Top Tips:

  1. How to properly post source code - see: https://www.avrfreaks.net/comment... - also how to properly include images/pictures
  2. "Garbage" characters on a serial terminal are (almost?) invariably due to wrong baud rate - see: https://learn.sparkfun.com/tutorials/serial-communication
  3. Wrong baud rate is usually due to not running at the speed you thought; check by blinking a LED to see if you get the speed you expected
  4. Difference between a crystal, and a crystal oscillatorhttps://www.avrfreaks.net/comment...
  5. When your question is resolved, mark the solution: https://www.avrfreaks.net/comment...
  6. Beginner's "Getting Started" tips: https://www.avrfreaks.net/comment...
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Yeah, but Clawson, your a Sassenach.  lol

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

My wife isn't though, she's the original Galway Girl ;-)

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Lucky you, have you been to Galway?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hi Clawson, you got my example to compile.  Can I ask you what IDE did you use and can I add the ARM toolchain to it?

Last Edited: Thu. Aug 16, 2018 - 06:00 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Fianawarrior wrote:

Lucky you, have you been to Galway?


We own a house in Co. Galway so, yeah, you could say I've been a few times (like 100+).
.
As I said above i built that with MSVC. I work with a legacy version (Visual Studio 2010) in fact but almost everything you wrote was "standard C" so that should have built with almost any C compiler. Because I'm a luddite I actually started with Notepad++ as my editor and invoking cl.exe at the command line but to use the debugger I later created a solution / project then included the .cpp file into that.

Last Edited: Thu. Aug 16, 2018 - 07:08 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Fianawarrior wrote:
... and can I add the ARM toolchain to it?
Yes

What's extra price (low) is arm GDB in Microsoft Visual Studio.

Sysprogs

Prebuilt GNU toolchain for arm-eabi

http://gnutoolchains.com/arm-eabi/

...

  • ARM Cortex A5

...

VisualGDB via tag:gdb in

https://marketplace.visualstudio.com/search?term=tag%3Agdb&target=VS&category=All%20categories&vsVersion=vs15&sortBy=Relevance

 

"Dare to be naïve." - Buckminster Fuller

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I'll get a look tomorrow at the MSCV

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Two things catch my eye in the code.

 

First, I would use typedef when declaring struct task_ctrl_obj. The way it's currently declared, some compilers will only give you a single instance of it.

 

Second, the static keyword on the declaration of api_program may be getting applied to the return type, rather than the function.

 

The combination of these two may result in a single struct placed at address 0 and the three calls to api_program return a static pointer to that address.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hi balisong42,

 

That's interesting what you have just said.  I'll check it shortly but I think your correct.  Lets hope so.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Nope never worked.  The pointers are now being initialised correctly.

 

The full code is listed below:

/** \file
 *
 *  This file contains all the specific code for the getting-started example.
 *
 */

/*----------------------------------------------------------------------------
 *        Headers
 *----------------------------------------------------------------------------*/
typedef char bool;
#define NULL ( (void *) 0)


#define false 0
#define true  !false


#include "board.h"
#include "chip.h"
#include "trace.h"
#include "compiler.h"
#include "timer.h"

#include "irq/irq.h"
#include "gpio/pio.h"
#include "peripherals/pmc.h"
#include "peripherals/tcd.h"

#include "serial/console.h"
#include "led/led.h"


#include "board_console.h"
#include "mm/l1cache.h"
#include "rand.h"


#include <malloc.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdint.h>


// Task Ctrl Block, Stores the Status and Task Properties
typedef struct task_ctrl_obj {

	unsigned char * stack_ptr;				// Task Stack Pointer saved by the contest switch
	unsigned char * stack_allocation;		// Pointer for De-allocation of Stack

	int  delay_counter;						// Task delay counter if zero then task is not waiting otherwise
											// we can assume that the task is waiting on a delay request

	unsigned char * mpu_base_mem_addr;
	unsigned char ergonRegion;
//	bool mpu_protection;

	char name[30];

	unsigned char	default_priority;		// Default Task Priority	0 - 63
	unsigned char	delta_priority;			// Task Run-time Priority	0 - 63

	unsigned char   total_futexs_held;		// Used to manage the priority inheritance
	unsigned char	ceiling_priority;		// Futex Ceiling priority
//	bool			sem_rw_type;

	unsigned char	task_status;			// Task Status, i.e., READY, WAITING, DORMANT, DELAYED
	unsigned char	internal_ctrl;			// Ctrl Status, i.e. TIMEOUT, SEMACK, etc
};

struct task_ctrl_obj  * OSTCBHighRdy;
struct task_ctrl_obj  * core_executing_task;


struct task_ctrl_obj * test1;
struct task_ctrl_obj * test2;
struct task_ctrl_obj * test3;




__attribute__((naked))static void run (void){

	__asm__ __volatile__(

			"MOV     R0, %[current_tcb]\n\t"
		    "MOV     R1, %[tcb_new]\n\t"
		    "LDR     R2, [R1]\n\t"
		    "STR     R2, [R0]\n\t"

		    "LDR     SP, [R2]\n\t"

			"POP     {r0}\n\t"					// Pop new task's FPEXC
            "FLDMIAS SP!, {S0-S31}\n\t"			//    ... Pop new task's General-Purpose floating point registers.
			"POP     {r0}\n\t"
			"VMSR    FPSCR, r0\n\t"				//    ... Pop new task's FPSCR.



		    "LDMFD   SP!, {R0}\n\t"
		    "MSR     SPSR_cxsf, R0\n\t"

		    "LDMFD   SP!, {R0-R12, LR, PC}" :: [current_tcb] "r" (&core_executing_task), [tcb_new] "r" (&OSTCBHighRdy));
}


struct task_ctrl_obj * api_program(void(*)(void), char const * name, void *, unsigned int, unsigned char, unsigned char);
struct task_ctrl_obj * api_program(void(*task)(void), char const * name, void * variable_pass, unsigned int mpu_mem, unsigned char priority, unsigned char ceiling ){
	//api_system_gateway();

	if(priority > 63){
		return(0);
	}

	struct task_ctrl_obj * tcb;

	tcb = malloc(sizeof(struct task_ctrl_obj));			// Allocate Memory for the Task Ctrl Block, used by the Kernel to manage the Task


	if(tcb == NULL){
		printf("\n\tError Allocating service TCB\n\r");
		return(NULL);
	}

		unsigned int stack;


		tcb->mpu_base_mem_addr = malloc(mpu_mem * sizeof(int));
		tcb->stack_allocation = (unsigned char *)tcb->mpu_base_mem_addr;


		stack = mpu_mem * sizeof(int);


		if(tcb->mpu_base_mem_addr == NULL){
			printf("\n\tError Allocating stack TCB\n\r");
			free(tcb);
			return(NULL);
		}

		unsigned int * cpu_core_stack = (unsigned int *)(stack + tcb->mpu_base_mem_addr);												// PointStack to the end of the memory structure, Stack grows upwards
		cpu_core_stack = (unsigned int *)((unsigned int)(cpu_core_stack) & 0xFFFFFFF8u);

		//tcb->task_status = DORMANT;											// Initial State of all Tasks is DORMANT

	/*
	 *	Prepare Task context
	 */

	/*
	 * Setup tcb priority
	 */
	tcb->delta_priority   = priority;									// Set Task Priority
	tcb->ceiling_priority = ceiling;
	tcb->default_priority = priority;									// Set Base Priority, used by the Priority inversion protocol



	/*
	 * Setup general purpose registers
	 */
     * cpu_core_stack-- = (unsigned int) task;											   /* R15/PC                                                    */
     * cpu_core_stack-- = (unsigned int) task;		                                  	   /* SR: Supervisor mode                                       */
     * cpu_core_stack-- = (unsigned int) 0x00000000;                                       /* R0                                                        */
     * cpu_core_stack-- = (unsigned int) 0x00000000;                                       /* R1                                                        */
     * cpu_core_stack-- = (unsigned int) 0x00000000;                                       /* R2				                                           */
     * cpu_core_stack-- = (unsigned int) 0x00000000;		                               /* R3							    		                   */
     * cpu_core_stack-- = (unsigned int) 0x00000000;                                       /* R4                                                        */
     * cpu_core_stack-- = (unsigned int) 0x00000000;									   /* R5				                                           */
     * cpu_core_stack-- = (unsigned int) 0x00000000;                                       /* R6                                                        */
     * cpu_core_stack-- = (unsigned int) 0x00000000;                                       /* R7                                                        */
     * cpu_core_stack-- = (unsigned int) 0x00000000;                                       /* R8                                                        */
     * cpu_core_stack-- = (unsigned int) 0x00000000;                                       /* R9                                                        */
     * cpu_core_stack-- = (unsigned int) 0x00000000;                                       /* R10                                                       */
     * cpu_core_stack-- = (unsigned int) 0x00000000;                                       /* R11                                                       */
     * cpu_core_stack-- = (unsigned int) variable_pass;                                    /* R12 ARGUMENT PASS                                         */


	#define  OS_CPU_ARM_BIT_CPSR_MODE_SUPERVISOR 0x13u
	#define  OS_CPU_ARM_BIT_CPSR_T (1u << 5u)

     // Stup Status registers
     * cpu_core_stack-- = (unsigned int)(0x00000100 | OS_CPU_ARM_BIT_CPSR_MODE_SUPERVISOR);



     {	/*
     	 *	Setup Floating Point registers
     	 **/
    	 *cpu_core_stack-- = 0x00000000;	 	/* Initialise Floating point status & control register  */

    	 for (int i = 0; i < 32; i++)
    		 * cpu_core_stack-- = 0x00000000;	/* Initialise general-purpose Floating point registers  */

    	 * cpu_core_stack = 0x40000000;  	 	/* Initialise Floating-Point Exception Register (Enable)*/
     }

//	internal_kernel_insert_task(tcb);											// insert task ctrl block unto Kernel Schedular
	tcb->stack_ptr = (unsigned char *)cpu_core_stack;													// Store Stack pointer unto the task ctrl block
	return(tcb);														// Return Handle to the newly Created Task
}



static void task1 (void){

	printf("Task 1 Running");
	while (1);
}

static void task2 (void){

	printf("Task 2 Running");
	while (1);
}

static void task3 (void){

	printf("Task 3 Running");
	while (1);
}

/**
 *  \brief getting-started Application entry point.
 *
 *  \return Unused (ANSI-C compatibility).
 */
int main(void)
{


	console_example_info("Getting Started Example");


	test1 = api_program(task1,"test" ,NULL ,4096 ,11 ,11);
	test2 = api_program(task2,"test" ,NULL ,4096 ,10 ,10);
	test3 = api_program(task3,"test" ,NULL ,4096 ,10 ,10);

	printf("\n\r\n\rtest1 %p", &test1);
	printf("\n\rtest2 %p", &test2);
	printf("\n\rtest3 %p", &test3);

	printf("\n\rtest3 %p", &OSTCBHighRdy);
	printf("\n\rtest3 %p", &core_executing_task);

	OSTCBHighRdy = test1;
	run();
}

and the serial output is:

 

-- Getting Started Example --
Softpack v2.12
Built for sama5d4-ek
Processor: SAMA5D44
Processor clock: 600 MHz
Master clock: 200 MHz
MMU is enabled
I-Cache is enabled
D-Cache is enabled
L2-Cache is disabled

test1 0x2000cb54
test2 0x2000cb60
test3 0x2000cb64
test3 0x2000cb58
test3 0x2000cb5cTask 3 Running

 

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Narrowed the error down to malloc.  I have no ideda how to go forward with this unless Microchip can provide a solution..

 

The following code


/** \file
 *
 *  This file contains all the specific code for the getting-started example.
 *
 */

/*----------------------------------------------------------------------------
 *        Headers
 *----------------------------------------------------------------------------*/
typedef char bool;
#define NULL ( (void *) 0)


#define false 0
#define true  !false


#include "board.h"
#include "chip.h"
#include "trace.h"
#include "compiler.h"
#include "timer.h"

#include "irq/irq.h"
#include "gpio/pio.h"
#include "peripherals/pmc.h"
#include "peripherals/tcd.h"

#include "serial/console.h"
#include "led/led.h"


#include "board_console.h"
#include "mm/l1cache.h"
#include "rand.h"


#include <malloc.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdint.h>


// Task Ctrl Block, Stores the Status and Task Properties
typedef struct task_ctrl_obj {

	unsigned char * stack_ptr;				// Task Stack Pointer saved by the contest switch
	unsigned char * stack_allocation;		// Pointer for De-allocation of Stack

	int  delay_counter;						// Task delay counter if zero then task is not waiting otherwise
											// we can assume that the task is waiting on a delay request

	unsigned char * mpu_base_mem_addr;
	unsigned char ergonRegion;
//	bool mpu_protection;

	char name[30];

	unsigned char	default_priority;		// Default Task Priority	0 - 63
	unsigned char	delta_priority;			// Task Run-time Priority	0 - 63

	unsigned char   total_futexs_held;		// Used to manage the priority inheritance
	unsigned char	ceiling_priority;		// Futex Ceiling priority
//	bool			sem_rw_type;

	unsigned char	task_status;			// Task Status, i.e., READY, WAITING, DORMANT, DELAYED
	unsigned char	internal_ctrl;			// Ctrl Status, i.e. TIMEOUT, SEMACK, etc
};

struct task_ctrl_obj  * OSTCBHighRdy;
struct task_ctrl_obj  * core_executing_task;


struct task_ctrl_obj * test1;
struct task_ctrl_obj * test2;
struct task_ctrl_obj * test3;




__attribute__((naked))static void run (void){

	__asm__ __volatile__(

			"MOV     R0, %[current_tcb]\n\t"
		    "MOV     R1, %[tcb_new]\n\t"
		    "LDR     R2, [R1]\n\t"
		    "STR     R2, [R0]\n\t"

		    "LDR     SP, [R2]\n\t"

			"POP     {r0}\n\t"					// Pop new task's FPEXC
            "FLDMIAS SP!, {S0-S31}\n\t"			//    ... Pop new task's General-Purpose floating point registers.
			"POP     {r0}\n\t"
			"VMSR    FPSCR, r0\n\t"				//    ... Pop new task's FPSCR.



		    "LDMFD   SP!, {R0}\n\t"
		    "MSR     SPSR_cxsf, R0\n\t"

		    "LDMFD   SP!, {R0-R12, LR, PC}" :: [current_tcb] "r" (&core_executing_task), [tcb_new] "r" (&OSTCBHighRdy));
}



struct task_ctrl_obj * api_program(void(*)(void), char const * name, void *, unsigned int, unsigned char, unsigned char);
struct task_ctrl_obj * api_program(void(*task)(void), char const * name, void * variable_pass, unsigned int mpu_mem, unsigned char priority, unsigned char ceiling ){
	//api_system_gateway();

	if(priority > 63){
		return(0);
	}

	struct task_ctrl_obj * tcb;

	tcb = malloc(sizeof(struct task_ctrl_obj));			// Allocate Memory for the Task Ctrl Block, used by the Kernel to manage the Task
	printf("\n\r%s tcb %p", name, &tcb);

	if(tcb == NULL){
		printf("\n\tError Allocating service TCB\n\r");
		return(NULL);
	}

		unsigned int stack;


		tcb->mpu_base_mem_addr = malloc(mpu_mem * sizeof(int));
		tcb->stack_allocation = (unsigned char *)tcb->mpu_base_mem_addr;
		printf("\n\r%s tcb %p", name, &tcb->mpu_base_mem_addr);

		stack = mpu_mem * sizeof(int);


		if(tcb->mpu_base_mem_addr == NULL){
			printf("\n\tError Allocating stack TCB\n\r");
			free(tcb);
			return(NULL);
		}

		unsigned int * cpu_core_stack = (unsigned int *)(stack + tcb->mpu_base_mem_addr);												// PointStack to the end of the memory structure, Stack grows upwards
		cpu_core_stack = (unsigned int *)((unsigned int)(cpu_core_stack) & 0xFFFFFFF8u);

		//tcb->task_status = DORMANT;											// Initial State of all Tasks is DORMANT

	/*
	 *	Prepare Task context
	 */

	/*
	 * Setup tcb priority
	 */
	tcb->delta_priority   = priority;									// Set Task Priority
	tcb->ceiling_priority = ceiling;
	tcb->default_priority = priority;									// Set Base Priority, used by the Priority inversion protocol



	/*
	 * Setup general purpose registers
	 */
     * cpu_core_stack-- = (unsigned int) task;											   /* R15/PC                                                    */
     * cpu_core_stack-- = (unsigned int) task;		                                  	   /* SR: Supervisor mode                                       */
     * cpu_core_stack-- = (unsigned int) 0x00000000;                                       /* R0                                                        */
     * cpu_core_stack-- = (unsigned int) 0x00000000;                                       /* R1                                                        */
     * cpu_core_stack-- = (unsigned int) 0x00000000;                                       /* R2				                                           */
     * cpu_core_stack-- = (unsigned int) 0x00000000;		                               /* R3							    		                   */
     * cpu_core_stack-- = (unsigned int) 0x00000000;                                       /* R4                                                        */
     * cpu_core_stack-- = (unsigned int) 0x00000000;									   /* R5				                                           */
     * cpu_core_stack-- = (unsigned int) 0x00000000;                                       /* R6                                                        */
     * cpu_core_stack-- = (unsigned int) 0x00000000;                                       /* R7                                                        */
     * cpu_core_stack-- = (unsigned int) 0x00000000;                                       /* R8                                                        */
     * cpu_core_stack-- = (unsigned int) 0x00000000;                                       /* R9                                                        */
     * cpu_core_stack-- = (unsigned int) 0x00000000;                                       /* R10                                                       */
     * cpu_core_stack-- = (unsigned int) 0x00000000;                                       /* R11                                                       */
     * cpu_core_stack-- = (unsigned int) variable_pass;                                    /* R12 ARGUMENT PASS                                         */


	#define  OS_CPU_ARM_BIT_CPSR_MODE_SUPERVISOR 0x13u
	#define  OS_CPU_ARM_BIT_CPSR_T (1u << 5u)

     // Stup Status registers
     * cpu_core_stack-- = (unsigned int)(0x00000100 | OS_CPU_ARM_BIT_CPSR_MODE_SUPERVISOR);



     {	/*
     	 *	Setup Floating Point registers
     	 **/
    	 *cpu_core_stack-- = 0x00000000;	 	/* Initialise Floating point status & control register  */

    	 for (int i = 0; i < 32; i++)
    		 * cpu_core_stack-- = 0x00000000;	/* Initialise general-purpose Floating point registers  */

    	 * cpu_core_stack = 0x40000000;  	 	/* Initialise Floating-Point Exception Register (Enable)*/
     }

//	internal_kernel_insert_task(tcb);											// insert task ctrl block unto Kernel Schedular
	tcb->stack_ptr = (unsigned char *)cpu_core_stack;													// Store Stack pointer unto the task ctrl block
	return(tcb);														// Return Handle to the newly Created Task
}



static void task1 (void){

	printf("Task 1 Running");
	while (1);
}

static void task2 (void){

	printf("Task 2 Running");
	while (1);
}

static void task3 (void){

	printf("Task 3 Running");
	while (1);
}

/**
 *  \brief getting-started Application entry point.
 *
 *  \return Unused (ANSI-C compatibility).
 */
int main(void)
{


	console_example_info("Getting Started Example");


	test1 = api_program(task1,"test 1" ,NULL ,4096 ,11 ,11);
	test2 = api_program(task2,"test 2" ,NULL ,4096 ,10 ,10);
	test3 = api_program(task3,"test 3" ,NULL ,4096 ,10 ,10);

	printf("\n\r\n\rtest1 %p", &test1);
	printf("\n\rtest2 %p", &test2);
	printf("\n\rtest3 %p", &test3);

	printf("\n\rOSTCBHighRdy %p", &OSTCBHighRdy);
	printf("\n\rcore_executing_task %p", &core_executing_task);

	OSTCBHighRdy = test1;
	run();
}

give this result:

 

-- Getting Started Example --
Softpack v2.12
Built for sama5d4-xult
Processor: SAMA5D44
Processor clock: 600 MHz
Master clock: 200 MHz
MMU is enabled
I-Cache is enabled
D-Cache is enabled
L2-Cache is disabled

test 1 tcb 0x2000dae4
test 1 tcb 0x2000d164
test 2 tcb 0x2000dae4
test 2 tcb 0x14
test 3 tcb 0x2000dae4
test 3 tcb 0x14

test1 0x2000cb54
test2 0x2000cb60
test3 0x2000cb64
OSTCBHighRdy 0x2000cb58
core_executing_task 0x2000cb5cTask 3 Running

 

thus malloc is fecked!

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

balisong42 wrote:
First, I would use typedef when declaring struct task_ctrl_obj. The way it's currently declared, some compilers will only give you a single instance of it.
His code is C++ not C so surely that syntax is fine?
Fianawarrior wrote:
thus malloc is fecked!
Make the allocations but DON'T do any of the writing to the allocated RAM. Does the problem persist?

 

The way malloc usually works (though implementations for various processors vary) is that either before or after each allocation there is some added "metadata" that provides the links between the memory blocks. If you over-write that you can seriously damage the heap and the ability for malloc() to continue.

 

One debug technique is to use a modified malloc that adds "guard bands" before and after each allocation you make. So you malloc(10) but it actually allocates 14 (say) with 2 bytes before and 2 bytes after the allocated block (the pointer returned is effectively allocated+2). Recognizable values like 0xA55A or something are written into the bytes before/after the allocation. Later, in free(), the code does the usual thing of return the allocation to the heap but before it does it inspects the guard bands to see if they still contain the "cookie" value. If not then the code has written before/after its allocated block and all hell then breaks loose. (actually it hopefully says something sensible like "over-run/under-run in block at %08X"

 

I think it VERY unlikely that the ARM Newlib implementation of malloc()/free() are "fecked" so it is a 99.9999999% chance it's something you are doing!

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

What size is the heap set to? Have a look at your linker script. 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Can't find it, I'm new to this sama5d44 bare metal.

 

EDITED:

I've searched the bare metal example folder and can't find it.

Last Edited: Sat. Aug 18, 2018 - 10:34 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Look at your build output - you’ll see what files are being used. Also look at the .map file, it too will say what file is being used.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Ok, I've just done a quick look at a saml21 project I was working on recently. It doesn't seem to have any heap, so it looks like you have to do some work yourself. There's plenty of references on Google, so get reading. 

Malloc() returns a null pointer if it can't give you your request. This seems to be what is happening here. Most likely, you need to provide some input, be it through the linker script and/or implementing _sbrk(). A linker script for a c++ project might be helpful as it will most likely implement the heap.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 1

Malloc() returns a null pointer if it can't give you your request. This seems to be what is happening here.

 

Really?  I thought FiannaWarrior's code explicitly checked for nulls returned from malloc():

    tcb = malloc(sizeof(struct task_ctrl_obj));			// Allocate Memory for the Task Ctrl Block, used by the Kernel to manage the Task
    printf("\n\r%s tcb %p", name, &tcb);

    if(tcb == NULL){

 

Also, since when does ASF/newlib/gcc-libc/etc NOT include a working malloc()?  (one of my standard complaints has been that even trivial stdio-using code ends up linking in malloc())

 

Perhaps this is a simple matter of needing to define a HEAPSIZE somewhere in the project definition?

 

Hmm.  Perhaps https://community.atmel.com/foru... is related?

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

yes, westfw, I just need to find the heap end ptr.