Página 1 de 1

MensagemEnviado: 28 Fev 2007 23:23
por JeanPaul
Estou usando dois registradores de endereço (R0 e R1) para implementar um buffer circular. Vou trabalhar com o buffer dentro de uma rotina de interrupção.
O que está pegando é que toda vez que saio da rotina de interrupção, os registradores são restaurados automaticamente para o valor que estava antes da interrupção, ou seja, perco as modificações feitas nesses registradores na rotina de interrupção.

Como disse, os registradores estão sendo restaurados automaticamente. Existe alguma forma de desabilitar o salvamento desses registradores no CodeWarrior?

Sei que posso salvar esses valores dentro da interrupção ou trabalhar com o buffer fora da rotina de interrupção, mas será que não tem jeito da forma que estou fazendo?

Obrigado a todos!

[]’s

Jean Paul

MensagemEnviado: 01 Mar 2007 12:58
por Fábio Pereira
Olá Jean Paul,

Em primeiro lugar, separei a sua mensagem do outro tópico.

Gostaria que você tivesse consciência de que, para facilitar a vida de todos os usuários do fórum, novos assuntos merecem novos tópicos. Não é interessante ficar alongando um tópico com informações que não estão diretamente relacionadas ao subject do tópico.

Pois bem, vamos então a sua pergunta:

Olha, eu não sou expert em 56F800e, aliás, sou apenas um curioso.

A sua questão me parece ter duas vias:

1- Se você estiver utilizando o modo de interrupções rápidas, deve saber que o hardware preserva automaticamente os registradores R0 e R1 (além do N e M01), além de salvar o SR na pilha;

2- Se estiver utilizando interrupções normais, você está utilizando a diretiva #pragma interrupt ? Dê uma olhada no help do CW, em Build Tools Reference > Pragmas Object Code Organization ... > interrupt

Outra coisa: ocupar permanentemente dois registradores da AGU pode não ser uma boa idéia. Mas se for para ocupar, porquê não outros registradores como R4 e R5 ?

Até +

MensagemEnviado: 01 Mar 2007 18:37
por JeanPaul
Olá Fábio,

Desculpe pelo tópico extenso. :oops:

Realmente é a diretiva #pragma interrupt que faz com que o compilador automatize o salvamento dos registradores, porém já percebi que não funciona bem da forma que eu estava imaginando. Dessa forma vou salvar o conteúdo de R0 e R1 e restaurar os valores durante a interrupção.

Quanto à ocupação permanente dos registradores R0 e R1, são apenas estes dois que o registrador modificador M01 libera para utilização como buffer circular.

A minha idéia era criar um buffer circular de amostras obtidas com o AD. Com a utilização de M01, R0 e R1 isso se torna praticamente automático, eu não teria que me preocupar com valores de incremento e coisa e tal.

Como uma dúvida puxa a outra ... consegui fazer o buffer para 16 amostras, funcionou perfeitamente. Defino uma tabela na memória RAM com 16 posições, passo o endereço do primeiro elemento para R0, 0x230 por exemplo, vou incrementando R0 e quando este chega em 0x23f automaticamente R0 volta para 0x230, tudo certo.

Porém acho que vou precisar de 32 amostras, daí o negócio complicou.
Defino uma tabela na memória RAM com 32 posições, passo o endereço do primeiro elemento para R0, 0x230 por exemplo, vou incrementando R0 e quando este chega em 0x23f o valor R0 passa para 0x220, sendo que a tabela foi alocada de 0x230 até 0x24F.

Pelo que entendi lendo os datasheets, o valor que deve ser passado para R0 deve ser o endereço do meio da tabela. Mas porque será que funcionou com a tabela de 16 posições? Bom, se passo o endereço + 16 posições da tabela de 32 posições (procurando o valor central), o valor de R0 vai sendo incrementado de 0x240 e, ao invés de voltar para 0x230 quando chega em 0x24F, vai embora até 0x25F ... é mole?

Bom, sei que é complicada essa questão e sei também que é uma coisa fácil de fazer por soft. Só achei que se o DSC possui essa funcionalidade, seria interessante utiliza - lá.

Bom Fábio, se você, ou mais alguém, tiver alguma sugestão do que fazer .... eu agradeço muito. Passei o dia inteiro fuçando sobre isso e já estou quase desistindo. :(

Mais uma vez obrigado.

[]'s

Jean Paul

MensagemEnviado: 04 Mar 2007 13:17
por JeanPaul
Problema “resolvido” da seguinte forma:

Aloquei a tabela como uma const. Isso fez com que o CW reservasse espaço no inicio da memória para esta tabela. Isso resolveu o problema do registrador retornar antes de chegar ao fim da tabela. Porem, o CW estava alocando a tabela sempre em endereços com inicio 2, 0x022 por exemplo, com isso eu ainda estava perdendo dois endereços da tabela.

Olhando no arquivo .cmd do projeto, notei que o CW dá um offset de 2 posições para que a memória RAM não inicie em 0x0000. :?: Mudei o valor do offset para zero e consegui rodar perfeitamente o buffer circular pelo HW. :shock:

Sei que foi uma solução meio que na base da gambiarra, mas pelo datasheet deveria ter funcionado sem qualquer modificação. Ainda não entendi o porquê do offset na memória RAM, mas por enquanto está funcionando. :?

[]’s

Jean Paul

MensagemEnviado: 04 Mar 2007 22:37
por KrafT
Os compiladores C costumam ser gananciosos no "Scratch Ram" que reservam pra sí...

Não será o caso?

MensagemEnviado: 05 Mar 2007 16:25
por JeanPaul
Pois é Kraft .... pode ser.

Tô vasculhando o manual do CW e até agora não achei nada referente à este offset. :?

[]'s

Jean Paul