Code in the vectors BUT keeping some of the C vectors

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

I have a need to have an ASM code table do an IJMP straight onto the reset vector and another straight into the middle of the interrupt vectors.

There are 3 ISR vectors after the IJMP point that are used.

At present I can sort out my problem by just making the HEX file and editing it in notepad to include my few bytes of code but obv. this is not a very good plan.

I have looked in avr-libc-user-manual.pdf in my install directory and done a search here for the answer. On here I get results telling me to

"make a local clone of gcrt1.s and modify it"

But I only have object files for gcrt1 in my install.

Can someone point me in the right direction or give me a document or source file that shows an example.

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

You can find it in the SVN repo of avr-libc or download the source of avr-libc.

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

but all you have to do is make the Z pointer 0 and then perform the ijmp....

so something like
ldi r30,0
ldi r31,0
ijmp

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

OK - I dont think I was clear enough there.

When I said I need to make an IJUMP that will go to the reset vector what I was implying was that

I need to do an IJUMP to a code table
I don't have enough time to fully calcuate a nice safe place to jump too
Two of the IJUMPs will end up in the middle of the vector table (0x0000, 0x0020)

I need to have my ASM code at 0x0000

0x0000  My code
0x0002  My code
0x0004  My code
0x0006  My code
0x0008  Work out if this is my IJUMP or a real reset and SKIP if my code
0x000A  JMP init/crt/main() (whatever normally happens at reset)
0x000C  My code
.
.
.
0x0020  My code for the other IJMP
0x0022  My code for the other IJMP
0x0024  My code for the other IJMP
0x0026  My code for the other IJMP
.
.
.
.

I already have this working by hand editing the HEX file. I would just like the compiler to do it for me.

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

andrewm1973 wrote:
I need to do an IJUMP to a code table
I don't have enough time to fully calcuate a nice safe place to jump too
???
It costs you absolutely no extra time to load something different than 0x00 into the high byte of Z.

Stefan Ernst

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

Oh - and before someone complains about the folly of putting my own code at address 0x0000

Here is what I have to do in 40 clocks

Read a Byte from an SD card for a 1 bit per pixel image
Que the next byte from the SD card
Read a byte from RAM that points to another ram location
Read the 16bit word pointed too (That is a 2bpp tile)
Combine the 1Bpp plane and the 2Bpp tile
Output the 8 pixels to a make a TV picture
(at evenly spaced 5 clock intervals)

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

sternst wrote:
andrewm1973 wrote:
I need to do an IJUMP to a code table
I don't have enough time to fully calcuate a nice safe place to jump too
???
It costs you absolutely no extra time to load something different than 0x00 into the high byte of Z.

It costs at least one clock cycle.

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

andrewm1973 wrote:
sternst wrote:
andrewm1973 wrote:
I need to do an IJUMP to a code table
I don't have enough time to fully calcuate a nice safe place to jump too
???
It costs you absolutely no extra time to load something different than 0x00 into the high byte of Z.

It costs at least one clock cycle.

How did the 0x00 (which is there now) get into it?

Stefan Ernst

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

sternst wrote:
andrewm1973 wrote:
sternst wrote:
andrewm1973 wrote:
I need to do an IJUMP to a code table
I don't have enough time to fully calcuate a nice safe place to jump too
???
It costs you absolutely no extra time to load something different than 0x00 into the high byte of Z.

It costs at least one clock cycle.

How did the 0x00 (which is there now) get into it?

As

LD r31, Y+

in between pixels 2 and 3.

Between pixels 3 and 4 I have to calculate the IJMP address as

MOV r30,r31
ANDI R31, 0x1F

Then after pixel 4 I have to IJMP

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

is the answer.... get a faster uC?

regards
Greg

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

The naive way of doing the code table would be

LD    Rn, Y+   ; Get the pixel Data
MUL   Rn, Rm   ; Multiply the JumpCode by entry size
MOVW  r30, r0  ; Copy Result of MUL to Z
ADD   R30, Ro  ; Add Base address of table lo8
ADC   R31, Rp  ; Add base address of table hi8
IJMP

You could set up a .section so that the start of your table is on a boundary and make "entry-size" an 2^n multiple. That will save you one ADD, but it is still not going to get you down enough in clocks to meet my timing requirments.

As I said - I don't have enough time to calculate the table address nicely. I have to take what addresses I can.

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

gregd99 wrote:
is the answer.... get a faster uC?

This is a challenge - not a commercial product.

If it wasn't being done for the fun of it it would just be on a CortexA15 with a powerVR 5xx

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

gregd99 wrote:
is the answer.... get a faster uC?

OH - I don't need help getting it working on this speed CPU. I've got that sorted in ASM. These little AVR CPUs are heaps fast :)

I am not smart enough to get the complier to mix my C and ASM in the unusual manner I want to. I have to resort to using Notepad to edit the hex file to add my instructions.

Hence I am asking the C smart people how to do it.

I have looked at the gcrt.s file now and I dont think that is my answer :( Back to google.

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

Quote:

I have looked at the gcrt.s file now and I dont think that is my answer

Well actually, yes, it is.

You just need to replace what that does with your own .S file. Just code what you require in a replacement of that file. Note how it builds the vector table at present:

	.macro	vector name
	.if (. - __vectors < _VECTORS_SIZE)
	.weak	\name
	.set	\name, __bad_interrupt
	XJMP	\name
	.endif
	.endm

	.section .vectors,"ax",@progbits
	.global	__vectors
	.func	__vectors
__vectors:
	XJMP	__init
	vector	__vector_1
	vector	__vector_2
	vector	__vector_3
	vector	__vector_4
	vector	__vector_5
	vector	__vector_6
	vector	__vector_7
	vector	__vector_8
	vector	__vector_9
etc.

You will only need as many of those as your AVR has vectors (so probably not all 127 shown there) and can replace selected ones with your own code:

	.macro	vector name
	.if (. - __vectors < _VECTORS_SIZE)
	.weak	\name
	.set	\name, __bad_interrupt
	XJMP	\name
	.endif
	.endm

	.section .vectors,"ax",@progbits
	.global	__vectors
	.func	__vectors
__vectors:
	XJMP	__init
	LDI R17,0x55
        RJMP foo
	vector	__vector_2
	vector	__vector_3
	SBIW R24, 12
        RJMP bar
	vector	__vector_5
	vector	__vector_6
etc.

Leave "vector __vector_N" entries for the vectors you do want to hook. Make sure that the replacement code for each is the same length as one vector entry.

Then compile with -nostartfiles so that crt.o is not linked and instead include this file in the build. The fact that it is in section ".vectors" ensures that the linker script will link it first to location 0.

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

Thank you Mr Lawson.

I'm not smart enough to understand any of what is going on there, but it is a point the right direction to help me work it out.

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

Stefan,

I just read back and I don't think I explained it quite so well.

I have a 8 bit wide pixel map.

I am making a 256 entry long code table to IJMP too.

I have to load the 8 bits and calculate the address of the entry point in 4.5 CPU clocks (4 clocks for the first 4 pixles and 5 clocks for the 2nd)

LD   r31, Y+   ; Load the 8 bits (4 pixels)
MOV  r30, r31  ; Copy to ZL
ANDI r31, 0x1F ; Clear top 3 bits of ZH

is 4 clocks and is effectivly gives me *32 (but jumbled)

LD   r31, Y+   ; Load the 8 bits (4 pixels)
MOV  r30, r31  ; Copy to ZL
ANDI r31, 0x1F ; Clear top 3 bits of ZH
ORI  r31, 0x40 ; Set b6 in ZH

is 5 clocks and is effectivly gives me *32+16535 (but jumbled)

The 2 drawbacks are that 2 of the entry points are smack bang in the middle of the vectors (Reset and WDT) and there is a 8Kbyte gap between the low 256 entries and the high 256 entries.

But overall is a reasonable solution because I can work around those problems (with all that .section stuff that confuses me)