.... Parece que voy a tener que centrarme en ARM nomas,
La verdad que siempre dicen que Microchip uso el compilador GCC lo trasformo y lo esta cobrando, si uno observa con detenimiento. Es verdad
version free XC32, PIC32MX de 16Kb, un pograma con 8 funciones y unas cuantas variables ya no entra, bien hecho microchip
version free XC32, PIC32MX de 16Kb, un pograma con 8 funciones y unas cuantas variables ya no entra, bien hecho microchip
Lo que noto yo al menos en lo que es ARM es que utiliza las rutinas memset de C, son larguisimas!. Y tal ves se puede achichar un poco mas.
Lo que noto yo al menos en lo que es ARM es que utiliza las rutinas memset de C, son larguisimas!. Y tal ves se puede achichar un poco mas.
lo bueno seria, (cuando hagas el tutorial ejem ejemm... :D :D) escribir las funciones en ASM y el programa principal en C
Y ya tenes un codigo que podes llamar desde C e.e lo unico que falta en C es que lo definas extern con el numero de argumentos que te guste xD
EDIT: Que tipo de funciones les gustaria ver implementado en ASM ? en el Ejemplo me refiero. no me digan Ethernet por que los mando a...
si queres algo por donde empezar.... pues mirá, estoy armando el esqueleto de lo que será el firm del cartel RGB y hasta ahora he creado este código:
Da lo mismo llamar una función como la esta definiendo el maestro Killer a tener el ASM embebido en la función en c?
En el caso que no sea lo mismo, como se definiria?
test.o: file format elf32-littlearm
Disassembly of section .text:
00000000 <_nrf_delay_us>:
0: 3801 subs r0, #1
2: 46c0 nop ; (mov r8, r8)
4: 46c0 nop ; (mov r8, r8)
6: 46c0 nop ; (mov r8, r8)
8: 46c0 nop ; (mov r8, r8)
a: 46c0 nop ; (mov r8, r8)
c: 46c0 nop ; (mov r8, r8)
e: 46c0 nop ; (mov r8, r8)
10: 46c0 nop ; (mov r8, r8)
12: 46c0 nop ; (mov r8, r8)
14: 46c0 nop ; (mov r8, r8)
16: 46c0 nop ; (mov r8, r8)
18: 46c0 nop ; (mov r8, r8)
1a: d1fe bne.n 0 <_nrf_delay_us>
1c: 4770 bx lr
Eso es un SPI, para mi deberias hacerlo por SPI (hasta aprovechar un QSPI o 2), tu "latch" seria el CS, seguro que podes mantener el CS hasta el ultimo dato enviado. Es decir enviar multiple bytes y luego recien ahi que se levante el CS. Y por hardware. Pero voy a intentar hacerlo. Indicame el micro que estas trabajando por que seguro que tengo que buscar los registros y esas cosas. Ya que por ejemplo vi que algunos poseen un registro especial para poner una salida a 1, mientras que otros usan la misma direccion para el encode.
PD: Estuve viendo y es un dolor de cabeza GCC sin optimizaciones :P
Y me esta siendo un dolor de cabeza acostumbrarme a ese ASM :P
Una cosa mas. Al comienzo es ponerle una constante, o tenes pensado hacer una funcion? si es asi pone como es la funcion. Ya que veo que estas enviando Rojo,Verde y Azul al 100%, todo terminaria en una constante e.e
MCH = 0x0000.0148
MCL = 0000 0bbb bbbb bggg gggg grrr rrrr r010
Estoy en lo correcto? Y b/r/g van a cambiar ? Y van a ser pasados por alguna funcion?
Que micro estamos hablando? Cortex-M3 ? M0+ ?
Por supuesto tengo el Cortex-M4F, asi que voy con esa arquitectura. si es un M0+ tenes que irte por la ARMv6-M , y el M4 y M7 posee una ARMv7E-M peeeeero es una v7 igual xD.
hombre ya que nos ponemos que sea de v7 para arriba :D :D, y si ya sabia lo de los lios que traen los ARM con la compatibilidad para procesadores y es un lio de cojones, por eso te preguntaba, por si acaso tu ya lo tenias claro :D :D
Lo unico claro que tengo es la piel por no salir al sol. Peeero mira como salieron las cosas del MPASM y dsPIC :P, solo ponerlo voluntad y en un dia te programas un satelite :D
seria cosa de checar cuantos ciclos toma cada instrucción
The number of cycles required for a pipeline refill. This ranges from 1 to 3 depending on the alignment and width of the target instruction, and whether the processor manages to speculate the address early.
.func emits debugging information to denote function name, and is ignored unless the file is assembled with debugging enabled.Asi que podriamos decir que no es si o si necesario ponerlo
De todas formas para eso esta el SYSTICK, Aunque te pases nuevamente por unos cuantos ciclos es mas exacto que estar acumulando errores (y ocuparia menos instrucciones creo :P).
La idea de Juanjo es mejor! empezar por el principio siempre es buena idea! :lol:+1
The cycle counts are based on a system with zero wait-states.
Y bue, quedo a la espera del comienzo formal del 'tuto'
CitarY bue, quedo a la espera del comienzo formal del 'tuto'
Me ponen entre la espada y la pared xD, lo mas lindo es que yo soy tan nuevo como todos ustedes en ASM de ARM. Asi que si.. estoy un poco (mucho) perdido.
Ahh y elgarbe hice el codigo que pedias, pero no me gusto :P lo veo muy largo xD
En algo le debo estar errando xD
T1 : ADD<c> <Rd>,<Rn>,#<imm3>
ADDS <Rd>,<Rn>,#<imm3>
T2 : ADD<c> <Rdn>,#<imm8>
ADDS <Rdn>,#<imm8>
T3: ADD{S}<c>.W <Rd>,<Rn>,#<const>
T4: ADDW<c> <Rd>,<Rn>,#<imm12>ADD R0,#1 ;Aumento en 1 X
CMP R0,#0x10 ;R0==10?
ITE EQ ; Esto no se ejecuta, solo es indicativo para lo siguiente, pero ocupa 16bits
ADDEQ R1,#1 ;Caso If Equal Then
SUBNE R1,#1 ;Caso Else o Not EqualMe ponen entre la espada y la pared xD, lo mas lindo es que yo soy tan nuevo como todos ustedes en ASM de ARM. Asi que si.. estoy un poco (mucho) perdido.
La diferencia es que vos ya estas familiarizado con los conceptos de ASM y nosotros ya nos olvidamos de todo. Modos de direccionamiento, set de instrucciones, etiquetas (.text, .func, etc). Pero bueno, tambien teens que ver que sea algo útil para futuros trabajos tuyos.+1
yo particularmente, siendo sincero, en este foro no me entero mas que del 25% tirando alto de lo que estáis hablando, así que hasta que no me ponga al dia no podre participar mucho :(
un saludo.
de ese modo puedo ir haciendo algo simple como para ir tomando contacto y por otra parte lo puedo testear en el micro. quizá se debería arrancar con ASM con cosas que tengan que ver con manejo de datos en memoria
Algo que creo está faltando es el formato genera de un archivo .s para que lo pueda meter en un pryecto y compile
Podrías intentar una función que tome un uint64 e invierta la posición de cada bit? El que esta en la posición 0 va a la pos 64 el del 1 a la pos 63 y así? Si fuese posible invertir la posición de 48 de los 64 bits mejor. Sería para reemplazar los for que tengo para enviar los datos y trabajar directamente con memoria para sacar los datos por spi...OK ahi veo el set de instrucciones como hacerlo
delay.s(1): error: A1137E: Unexpected characters at end of line
No se que tan errado este en el funcionamiento del programa, eso seria para invertir los bitsCódigo: ASM
.syntax unified .thumb .text .global Invertir ;@Funcion ASM que invierte los 49bits de una variable de 64bits ;@ Entrada R1:R0 ;@ Salida R1:R0 Variable de 64 bits Invertir: RBIT R2, R1 ;@ R2 = Inv(R1) RBIT R0, R0 ;@ R0 = Inv(R0) LSRS R2, R2, #15 ;@ R2 = Inv(R1) >> 15 UBFX R3, R0, #0 ,#14 ;@ R3 = R0[14:0] ADD.W R3, R2, R3, LSL #17 ;@ R3 = R0[14:0] + Inv(R1)>>15 = Bajo Invertido Final LSLS R1, R0, #15 ;@ R1 = R0[31:15]>>15 = Alto invertido Final MOVS R0, R1 ;@ R0 = Bajo Invertido Final BX LR ;@ Voler .end ;@ Normal ;@ 0x0001.1234.5678.9ABC -> ;@ Alto R1 0000 0000 0000 000,1 0001 0010 0011 0100 ;@ Bajo R0 0101 0110 0111 1000 1001 1010 1011 1100 ;@ Invertido: ;@ 0x0000.7AB2.3CD4.5891 ;@ Alto R1 0000 0000 0000 000,0 0111 1010 1011 0010 ;@ Bajo R0 0011 1100 1101 010,0 0101 1000 1001 0001 ;@ Normal invertido pero cada uno Despues del RBIT: ;@ Alto R1 0010 1100 0100 1000 1000 0000 0000 0000 ;@ Bajo R0 0011 1101 0101 1001 0,001 1110 0110 1010 ;@ Shift R1>>15 ;@ Alto R1 0000 0000 0000 000,0 0101 1000 1001 0001
Aunque seguro que si uso un par de Rotate sea mas corto... Ya voy a ver si logro hacerlo mas corto aun. lo que si puedo tener errores en el tema de los desplazamientos. esta complicado dividir todo por parte xD
Ahi utilize el Rotate y quedo mas corto. Sigo teniendo problemas para encontrarle la vuelta a esto de las funciones. No son demasiados claros, ni dan ejemplos ni nada, solo te ponen un pseudocodigo que tenes que adivinar que es.Código: ASM
Invertir: RBIT R2, R1 ;@ R2 = Inv(R1) RBIT R0, R0 ;@ R0 = Inv(R0) RORS R0, R0, #15 ;@ R0 = Inv(R0) >> 15 Wrap UBFX R1, R0, #0 ,#17 ;@ R1f = R0[16:0] = Alto invertido Final LSL R2, R2, #15 ;@ R2 = R2>>15 = R0f[16:0] BFI R0, R2, #0, #17 ;@ R0 = R0f[32:17] + R0f[16:0] BX LR ;@ Volver .end ;@ Normal ;@ 0x0001.1234.5678.9ABC -> ;@ Alto R1 0000 0000 0000 000,1 0001 0010 0011 0100 ;@ Bajo R0 0101 0110 0111 1000 1001 1010 1011 1100 ;@ Invertido: ;@ 0x0000.7AB2.3CD4.5891 ;@ Alto R1 0000 0000 0000 0000 0111 1010 1011 0010 ;@ Bajo R0 0011 1100 1101 0100 0101 1000 1001 0001 ;@ Normal invertido pero cada uno Despues del RBIT: ;@ Alto R2 0010 1100 0100 1000 1.000 0000 0000 0000 ;@ Bajo R0 0011 1101 0101 1001 0001 1110 0110 1010 ;@ ROR R0>>15 = R0[32:17] + R1 ;@ 0011 1100 1101 010.0 0111 1010 1011 0010 ;@ UBFX R1, R0, #0, #16 ;@ Alto R1 0000 0000 0000 0000 0111 1010 1011 0010 - Final ;@ LSL R2, R2, #15 ;@ R2 = 0000 0000 0000 0000 0101 1000 1001 0001
Sorprendentemente logre que compilara bien al instante, que sea correcto eso SI que no tengo ni idea.
Esto de no tener un maldito simulador de ARM lo estoy odiando. Si hay o son para ASM ARM o para micros de 5mil años atras. Y no tengo ganas de instalar QEMU e.e
MC uint64_t 1100101100000000000000000111111111111111111111011 (Binary)
inv uint64_t 1101111111111111111111110000000000000000000000000 (Binary)
MC uint64_t 1100101100000000000000000111111111111111111111011 (Binary)
inv uint64_t 1111111110000000000000000000000011111111100000000000000000000000 (Binary)
R1: 00000000 00000001 10010110 00000000
R2: 00000000 01101001 10000000 00000000
R0: 00000000111111111111111111111011
R0: 11011111111111111111111100000000
R0: 11111110 00000001 10111111 11111111
R1: 00000000 00000001 10111111 11111111
R2: 11000000 00000000 00000000 00000000
R0: 11111110 00000000 00000000 00000000
00000000 00000001 10111111 11111111 - 11111110 00000000 00000000 00000000
original 00000000 00000001 10010110 00000000 - 00000000 11111111 11111111 11111011
final 00000000 00000001 11011111 11111111 - 11111111 00000000 00000000 01101001
R1 R0R1: 00000000 00000001 10010110 00000000 @Valor sin invertir
R2: 00000000 01101001 10000000 00000000 @Invertidos
R3: 11011111 11111111 11111111 00000000
R1: R1f[31:16] : XX
R2: R0f[15:0] : XX
R3: R1f[15:0] : R0f[31:16]Gracias a la info de Leonardo sobre el DWT pude testear la funcion de delay en un M3 y me cuenta los 16 ciclos esperados, para los que usen psoc5lp acá dejo el código:
Lo que me parece raro son esos 37 ciclos. son demasiados.
Hay 6 instrucciones, de 32bits, no se si tomarlas como 12 ciclos o 6,
Supongamos 12, que luego por el pipeline se introduzca algunas bubbles por necesidad de los datos. eso lo aumentaria a cerca de 3 ciclos mas.
Sigiuiendo tenes el CALL y RETURN ( BL y BX ) eso va a depender exactamente del PC a donde se dirija, si es un salto a registro y no un literal, tomaria 3 ciclos, si es un literal 2 ciclos, si es un salto el cual no esta alineado a 32 bits tomaria 4 ciclos. entonces supongamos:
12 + 3 + 4 = 17 maximo.. incluso haciendo el doble en las instrucciones el cual NO deberia.
Código: ASM
Invertir: RBIT R2, R1 ;@ R2 = Inv(R1) RBIT R3, R0 ;@ R0 = Inv(R0) LSRS R2, R2, #16 ;@ R2: 00 : R0f[15:0] PKHTB R1, R1, R3, ASR #16 ;@ R1f[31:16]:R1f[15:0] = R1[31:16]:R3[31:16] = R1 PKHBT R0, R2, R3, LSL #16 ;@ R0f[31:16]:R0f[15:0] = R3[15:0]:R2[15:0] = R0 (Aca R2 esta luego del Shift, sino hubiera sido [31:16]) .end
Una sola instruccion menos .... :/, crei que lo podia hacer con 4 pero no pude...
y 3 bytes menos en memoria de programa, por que el LSRS ocupa 16 bytes
(despues les cuento un error en las librerías HAL que me tuvieron 2 días renegando con el SPI :5] en otro proyecto)
MUERTE A ST!!!!! :D :D :D otro que no quiero ni regalado como PIC32 :D :D
No te enojes juanjo, tambien hay funciones que no son bloqueantes :P y hacen lo mismo
Lo que si, no hay una funcion de "Enviar" y "Recibir" el DataPut sirve para enviar en su forma bloqueante o no.
Build error: cannot honor width suffix -- `rors r0,r0,#3'
| x | y | z | Description | Example |
| 7 | ARM7 core Version | ARM7 | ||
| 9 | ARM9 core Version | ARM9 | ||
| 10 | ARM10 core Version | ARM10 | ||
| 11 | ARM11 core Version | ARM11 | ||
| 1 | Cache, write buffer and MMU | ARM710 | ||
| 2 | Cache, write buffer and MMU, Process ID support | ARM920 | ||
| 3 | Physically mapped cache and MPU | ARM1136 | ||
| 4 | Cache, write buffer and MPU | ARM940 | ||
| 5 | Cache, write buffer and MPU, error correcting memory | ARM1156 | ||
| 6 | No cache, write buffer | ARM966 | ||
| 7 | AXI bus, physically mapped cache and MPU | ARM1176 | ||
| 0 | Standard cache size | ARM920 | ||
| 2 | Reduced cache | ARM1022 | ||
| 6 | Tightly Coupled Memory | ARM1156 | ||
| 8 | As for ARM966 | ARM968 |
| Attribute | Description |
| D | Supports debugging via the JTAG interface. Automatic for ARMv5 and above |
| E | Supports Enhanced DSP instructions. Automatic for ARMv6 and above |
| F | Supports hardware floating point via the VFP coprocessor |
| I | Supports hardware breakpoints and watchpoints. Automatic for ARMv5 and above |
| J | Supports the Jazelle Java acceleration technology |
| M | Supports long multiply instructions. Automatic for ARMv5 and above |
| T | Supports Thumb instruction set. Automatic for ARMv5 and above |
| -S | This processor uses a synthesizable hardware design |
Differences between ARM7 and ARMv7
This is a common question — and a common mistake. There is no comparison possible; the ARM7 is a core, whereas ARMv7 is an architecture.
The Cortex-A family is the computer family; the Application processors.
The Cortex-R family is the fast reacting family, the Real-time processor series.
The Cortex-M family is the ultra-low-powered, small form-factor family, the Micro-controller series.