collapse

* Posts Recentes

Amplificador - Rockboard HA 1 In-Ear por almamater
[27 de Março de 2024, 19:13]


O que é isto ? por KammutierSpule
[26 de Março de 2024, 19:35]


Bateria - Portátil por almamater
[25 de Março de 2024, 22:14]


Emulador NES em ESP32 por dropes
[13 de Março de 2024, 21:19]


Escolher Osciloscópio por jm_araujo
[06 de Fevereiro de 2024, 23:07]


TP4056 - Dúvida por dropes
[31 de Janeiro de 2024, 14:13]


Leitura de dados por Porta Serie por jm_araujo
[22 de Janeiro de 2024, 14:00]


Distancia Cabo por jm_araujo
[08 de Janeiro de 2024, 16:30]


Meu novo robô por josecarlos
[06 de Janeiro de 2024, 16:46]


Laser Engraver - Alguém tem? por almamater
[16 de Dezembro de 2023, 14:23]

Autor Tópico: Assembly junto com C em PIC  (Lida 7550 vezes)

0 Membros e 1 Visitante estão a ver este tópico.

Offline artur36

  • Mini Robot
  • *
  • Mensagens: 795
Assembly junto com C em PIC
« em: 29 de Maio de 2014, 16:58 »
Boas
Precisava de implementar uma sub-rotina em assembly dentro de um programa em C, de modo a ter controlo absoluto sobre os tempos para implementar uma rotina simples de comunicação a alta velocidade.
Pelo que li na app-note da microchip um dos cuidados a ter é garantir que as instruções em assembly não mudam de página de memória a meio da rotina, no entanto não percebi como fazer isso, se alguém poder dar umas dicas agradecia.
O pic a usar é o 16f1936 mas penso que o procedimento seja o mesmo para qualquer um.

App-note: http://ww1.microchip.com/downloads/en/AppNotes/00669.pdf

Offline msr

  • Mini Robot
  • *
  • Mensagens: 798
Re: Assembly junto com C em PIC
« Responder #1 em: 29 de Maio de 2014, 17:05 »

Offline artur36

  • Mini Robot
  • *
  • Mensagens: 795
Re: Assembly junto com C em PIC
« Responder #2 em: 30 de Maio de 2014, 14:22 »
O meu orblema não é como introduzir o assembly dentro do C, isso sei que é com os comandos #asm e #endasm. A minha dúvida prende-se em como definir a posição de memória em que o assembly vai ficar guardado no micro para garantir que não existe mudança de página de memória, ou caso esta mudança seja inevitável sei sempre onde colocar o código para alterar o PCLATH.
Pelo que depreendo da app-note que indiquei acima devo usar o código: "#pragma memory rom", mas não encontro informação concreta de como usar o comando, nomeadamente onde o devo colocar, se antes ou depois do #asm, e se é necessário algum comando extra depois para indicar que já não é importante a posição do código na memória.

P.S.: MSR o link que deixas-te refere-se a sistemas x86 e não a microcontroladores PIC.

Offline senso

  • Global Moderator
  • Mini Robot
  • *****
  • Mensagens: 9.733
  • Helpdesk do sitio
Re: Assembly junto com C em PIC
« Responder #3 em: 30 de Maio de 2014, 15:19 »
Se usares um compilador baseado em GCC, as directivas serão iguais, como falas ai em #pragma, deves estar a usar Hi-tech ou algo parecido.
Se usasses o GCC, ao usares o memory(::); depois de um pedaço de código isso diz ao compilador para não re-ordenar as instruções, por exemplo para o impedir de re-ordenar definições de flags.
Mas se precisas de mais capacidade de processamento, porque não passar para um micro mais capaz?
Avr fanboy

Offline artur36

  • Mini Robot
  • *
  • Mensagens: 795
Re: Assembly junto com C em PIC
« Responder #4 em: 30 de Maio de 2014, 16:05 »
Se usares um compilador baseado em GCC, as directivas serão iguais, como falas ai em #pragma, deves estar a usar Hi-tech ou algo parecido.
Se usasses o GCC, ao usares o memory(::); depois de um pedaço de código isso diz ao compilador para não re-ordenar as instruções, por exemplo para o impedir de re-ordenar definições de flags.
Mas se precisas de mais capacidade de processamento, porque não passar para um micro mais capaz?

Uso MPLab com xc8, pelo que vi na ajuda do MPLab devo ter de usar #pragma code, se colocar #pragma memory ao compilar indica que o comando não é reconhecido.


Segundo a ajuda:
Citar

Locating Code
Following a #pragma code directive, all generated code will be assigned to the specified code section until another #pragma code directive is encountered. An absolute code section allows the location of code to a specific address. For example:
#pragma code my_code=0x2000
will locate the code section my_code at program memory address 0x2000.
The linker will enforce that code sections be placed in program memory regions however, a code section can be located in a specified memory region. The SECTION directive of the linker script is used to assign a section to a specific memory region. The following linker script directive assigns code section my_code1 to memory region page1:
SECTION NAME=my_code1 ROM=page1

Não consegui ainda perceber foi o comando section name, e a sintax do #pragma code.
Devo colocar o ""#pragma code my_code= 0x200" no ínicio do código junto com os restantes pragma de definições  de registos sendo my_code o nome da sub-rotina e 0x200 a localização que quero?

Offline msr

  • Mini Robot
  • *
  • Mensagens: 798
Re: Assembly junto com C em PIC
« Responder #5 em: 30 de Maio de 2014, 17:59 »
As secções de código são definidas no linker, um ficheiro com extensão ".ld". Aí podes dar o nome à secção e definir o endereço de origem (ou então o tamanho, depende dos linkers). Depois no código já podes especificar a secção. A forma como isso é feito depende do compilador mas como já viste deves ter de usar um #pragma.
Se fosse gcc seria algo deste genero:
http://stackoverflow.com/questions/4756489/how-do-i-specify-output-sections-in-c-files-compiled-using-gcc

edit: artur36, o link que dei era só para dar um exemplo de como escrever código assembly "no meio" de ficheiro .c, a arquitectura e instruções eram irrelevantes
« Última modificação: 30 de Maio de 2014, 18:01 por msr »

Offline artur36

  • Mini Robot
  • *
  • Mensagens: 795
Re: Assembly junto com C em PIC
« Responder #6 em: 31 de Maio de 2014, 19:51 »
Após uma longa batalha o google e com o manual do xc8 acho que encontrei a solução. No manual do xc8 consegui perceber que os códigos que referi em cima não funcionam com este compilador e apenas posso usar as Program Sections para garantir localização do código.
Do que percebi do manual do xc8 ao definir uma PSec o compilador vai garantir que esta fica junto com outras secções idênticas e na mesma página de memória, é isto não é?
Abaixo fica o exemplo para criar uma PSect manualmente numa rotina assembly de um ficheiro.asm individual:
Código: [Seleccione]
#include <xc.inc>
GLOBAL _add ; make _add globally accessible
SIGNAT _add,4217 ; tell the linker how it should be called
; everything following will be placed into the mytext psect
PSECT mytext,local,class=CODE,delta=2
; our routine to add to ints and return the result
_add:
; W is loaded by the calling function;
BANKSEL (PORTB) ; select the bank of this object
ADDWF BANKMASK(PORTB),w ; add parameter to port
; the result is already in the required location (W)so we can
; just return immediately
RETURN

Este exemplo está na página 202 do manual do xc8 e é explicado nas páginas anteriores.

Segundo o que percebi do manual o comando SIGNAT serve para fazer a verificação da validade dos dados passados para a função, é isso?
Segundo o manual este código apesar de aconselhável é opcional, devo implementar ou não, uma vez que a minha função apenas vai receber um byte através do registo auxiliar W?