Go Down

Topic: Program Counter (PC) (Read 3 times) previous topic - next topic

jcisne7

May 07, 2012, 11:38 am Last Edit: May 08, 2012, 08:19 am by jcisne7 Reason: 1
Hi all!
Does anyone know how to manipulate the PC of the Atmega trough Arduino environment?
I'm making a real time multitask operative system for a university project and I have to address the PC to a location in the flash memory where  I previously loaded a task.

This is a pseudoce of I want to do:

Code: [Select]
struct PCB {
 int identifier;
 int start_address;
 int execution_address;
 int process_status;
 int accumulator;
 int word_status;
};

struct partition {
 int idp;
 int start_p;
 int end_p;
 int status_p;
 int size_p;
};

PCB process[100];
int queue_process[100];
int cmd; int npc;

partition memory[100];
int cpartitions = 6;

void setup(){
for (int i = 0;i <= 5 ;i++){
memory[ i].idp = 1;
memory[ i].start_p = 4096 + 4096*i;
memory[ i].end_p = 8192 + 4093*i;
memory[ i].status_p = 0;
memory[ i].size_p = 4096;
}  //making 6 partitions of the memory of 4k-size each
}

void loop(){
//cmd = leer comando();
/*switch(cmd){
 case 1:
   load_process()
 case 2:
   download_process()
 ...
}*/
if(process[queue_process[0]].status_process == 1){
 start_Timer();
 process[queue_process[0]].status_process = 2;
 [color=red]PC = process[queue_process[0]].start_address,[/color]
}
else{
 recover_environment();
 start_Timer();
 [color=red]PC = process[queue_process[0]].execution_address;  [/color]
}
}



That's just the main part of the hole code...
I just can't figure out how to load a value to the PC.
I will be waiting for any feedback... Thanks in advance!

Graynomad

Code: [Select]
PC = x
That certainly won't work, AFAIK there is no way to directly change the PC on an AVR. You can call a function using the __NAKED (?) directive so you know exactly where the PC is, dork the value on the stack and return.

Bit dodgy though.

______
Rob
Rob Gray aka the GRAYnomad www.robgray.com

jcisne7

#2
May 07, 2012, 04:39 pm Last Edit: May 08, 2012, 08:18 am by jcisne7 Reason: 1
Hi Graynomad, thanks for your time.
I know PC = x won't work, that's why I'm asking in this forum another way to do that.

Process (tasks) will be added via Serial communication so I'll know where they exactly begin and end.

Graynomad

#3
May 07, 2012, 04:56 pm Last Edit: May 07, 2012, 04:59 pm by Graynomad Reason: 1
Quote
//making 6 partitions of the memory of 4k-size each

Which chip are you using? That's a heck of a lot of RAM.

Here's some excerpts from a monitor program I wrote a while back, it was an ISR but I think NAKED works with functions as well. You probably don't need to save all the regs.

Code: [Select]
ISR (WDT_vect, ISR_NAKED) {
 
  /////////////////////////////////////////////
  // DIY prologue so I know exactly where the
  // program counter and working registers are
  asm (
    "push r0\n"
    "in r0,0x3f\n"
    "push r0\npush r1\npush r2\npush r3\npush r4\n"
    "push r5\npush r6\npush r7\npush r8\npush r9\n"
    "push r10\npush r11\npush r12\npush r13\npush r14\n"
    "push r15\npush r16\npush r17\npush r18\npush r19\n"
    "push r20\npush r21\npush r22\npush r23\npush r24\n"
    "push r25\npush r26\npush r27\npush r28\npush r29\n"
    "push r30\npush r31\n"
  );  // 33 bytes on the stack
....

    case  CMD_PC:
       address = (byte*)(SPL + (SPH << 8));
       address += 35; // skip 33 preamble bytes,
                      // +1 to allow for SP post decrement
                      // +1 because it seems to work ??
       resp_lo = *(address+1);
       resp_hi = *address;
       break;
....


This was used to return the PC but could also be used to change it.

I gather the "tasks" will be located in that memory you allocated, in which case you can use the address of the base of each block if I understand you correctly.

______
Rob
Rob Gray aka the GRAYnomad www.robgray.com

jcisne7

Hi again Graynomad!

I think I'm not getting what your code given does.
I've never programmed an aTmega in assembly language before and I don't understand what you mean with "__Naked". Despite this, I think that's what I'm looking for, if  as you say, it could be use to modify the PC value.

Could you please explain this in detail to me? ...if it isn't bothering much.   :smiley-red:

Quote
//making 6 partitions of the memory of 4k-size each
Which chip are you using? That's a heck of a lot of RAM.


Those partitions will be made in Flash memory.

Graynomad

Quote
Those partitions will be made in Flash memory.

I'm not getting this, what are these partitions for?

They can't be modified dynamically so they just house static functions do they? In which case why can't you just call them?

NAKED stops the compiler from doing any preamble at the start of a function. It's the only way I know of having things placed exactly where you want them because normally the compiler will push stuff onto the stack according to what it thinks is best on the day.

But I have to say all this is sounding a bit sus,

Code: [Select]
case 1:
    load_process()
  case 2:
    download_process()


You can't "download" a process into flash memory, so as I said you may was well just call functions.

______
Rob

Rob Gray aka the GRAYnomad www.robgray.com

jcisne7

Hi!
Sorry if I can't express what I can my code to do, I'm not quite good at English.

Yeah, you are right I can't "download" anything from the flash memory =)

The OS start whit no processes/tasks inside, just with this partition in the flash. With an interface made in C# I sent a byte that is read in:
Code: [Select]
cmd = leer comando();
Then, say cmd = 1 :
Code: [Select]
load_process()
The microcontroller  will look for an empty partition and with enough size (in the example given every partition have the same size so this is not so important) and then write the "code" of that process in that partition and set memory.status_process = 1.
When I want to download that process (cmd = 2) just clear memory = 0 ; so the microcontroller won't execute it any more.

When another process is load in that partition, it will be just overwritten and set again  memory.status_process = 1.

And, as the start position, size and end position of the process is know, there will be no problem =)

Tell me if yo get what I mean, and what you recommend me to do... How can I use "NAKED" in order to address the PC?

Thanks in advance!

Jack Christensen


I just can't figure out how to load a value to the PC.


Instructions such as JUMP, CALL, Branch, etc. load new values into the program counter, yes? Not sure I understand this project, but certainly some assembly code will probably be needed.
MCP79411/12 RTC ... "One Million Ohms" ATtiny kit ... available at http://www.tindie.com/stores/JChristensen/

justjed


I'm making a real time multitask operative system for a university project and I have to address the PC to a location in the flash memory where  I previously loaded a task.


If I understand what you're trying to do, you'll be doing some of the things that the Arduino bootloader does. The bootloader, at startup, will see if there's a new sketch to download, and if so, then do that, storing the code into memory, and then transfer control to that code. If there's no new sketch to download, then it transfers control to the already stored sketch. Thus, it seems like you might find it instructive to read the code for the bootloader. I'm not sure where to point you for that.
... it is poor civic hygiene to install technologies that could someday
facilitate a police state. -- Bruce Schneier

Graynomad

Quote
write the "code" of that process in that partition

I still don't follow this. You cannot write into flash unless you plan to write a custom bootloader of some sort, so where are these partitions.

One of us is barking up the wrong tree I think.

______
Rob
Rob Gray aka the GRAYnomad www.robgray.com

jcisne7

I thought writing in the flash was an easy thing, maybe it would be better to write processes in the EEPROM, and... as blinking (two) leds at different frequencies is enough for the purposes of the course I think size wont be a problem (Am I right?).


Anyone of you have idea if this would be easier to implement in a PIC (18F4550)? It is being used for the rest of my classmates and it seems they are not having so much problems... =/

Graynomad

#11
May 08, 2012, 04:09 pm Last Edit: May 08, 2012, 04:13 pm by Graynomad Reason: 1
Quote
I thought writing in the flash was an easy thing

No.

Quote
maybe it would be better to write processes in the EEPROM

That is easy, but you can't execute code from EEPROM.

Quote
Anyone of you have idea if this would be easier to implement in a PIC (18F4550)?

I'm not that familiar with PICs but the basic principles are the same so I can't see it being any easier, but maybe.

Quote
It is being used for the rest of my classmates and it seems they are not having so much problems... =/

Maybe they are asking different questions. I can't believe they are writing a multi-tasking OS for this, yet that seems to be what you want to do.

Quote
as blinking (two) leds at different frequencies is enough for the purposes of the course I think size wont be a problem (Am I right?).

You can load parameters into EEPROM and perform different actions based on them, but you can't load code. You could even load a script into EEPROM or RAM and interpret that. But with these small AVRs you cannot load executable code anywhere unless you write a bootloader.

Maybe you should explain exactly what you need to achieve rather than assuming that writing directly to the PC is the way to go.

_____
Rob

Rob Gray aka the GRAYnomad www.robgray.com

jcisne7

well , as you said.. I had to describe the process since beginning.... in the project, I have to do multitask, but the problem is that I dont know how to manipulate the "PC" of the arduino..Take for example, in the pic16f877A, i only have to change the value of the "pcl", but in the arduino I didnt find a way to manipulate the "PC" , when my process enter in a interruption, the process only returns to the line when the interrupt ocurred or in other lines before that , but i dont know how to jump to other parts of the code. This is the exactly problem that i have, i have read about the "pc" of the arduino, but its complicate to understand exactly how it works.

Graynomad

Then you will have to do some inline assembler, my assembler is very rusty so don't expect these to work out of the box

Code: [Select]
ISR (XXX_vect, ISR_NAKED) {
  asm (
    "pop r0\n"   // remove PC value from stack
    "pop r0\n"
    // load new PC into regs 30 and 31 (I can't remember how to reference an external C function address)
    "push r30\n"
    "push r31\n"
    "reti\n"
  );


Or maybe this, but it won't auto clear any interrupt flags or indeed re-enable interrupts

Code: [Select]
ISR (XXX_vect, ISR_NAKED) {
  asm (
    "pop r0\n"   // remove PC value from stack
    "pop r0\n"
    // load new PC into regs 30 and 31
    "ijmp\n"
  );


But you still haven't solved how you are going to download tasks into memory so until you solve that problem all this is moot. You apparently refuse to acknowledge that fact or explain exactly what has to be downloaded. Are you telling me that on a PIC you can load code into flash using a non-bootloader program?

Also there are different types of multi-tasking, you can of course do cooperative whereby each task just returns to the main loop. Has preemptive multi-tasking been specified? Even if it has the above is a 1000 miles away from working as a preeemptive task switcher, it doesn't save the machine state for a start.

______
Rob
Rob Gray aka the GRAYnomad www.robgray.com

justjed


You cannot write into flash unless you plan to write a custom bootloader of some sort


Tangential, I guess. Where are sketch variables stored? SRAM? Or, for that matter, malloc'd space? The malloc docs don't really specifically state that, or I'm not reading it very well.
... it is poor civic hygiene to install technologies that could someday
facilitate a police state. -- Bruce Schneier

Go Up
 

Quick Reply

With Quick-Reply you can write a post when viewing a topic without loading a new page. You can still use bulletin board code and smileys as you would in a normal post.

Warning: this topic has not been posted in for at least 120 days.
Unless you're sure you want to reply, please consider starting a new topic.

Note: this post will not display until it's been approved by a moderator.
Name:
Email:

shortcuts: alt+s submit/post or alt+p preview