# active low, active high

http://blog.naver.com/bab102/70035446144
http://www.reconfig-systems.com/8051lecture.htm#active_high

예를 든다면 어떤 칩이 high일때 동작하고 low일때 sleep 모드로 진입한다면 이건 active high이다.



# assert, deassert
http://help.lockergnome.com/linux/meaning-assert-deassert--ftopict280447.html

Given the copious context you've provided, this is just a guess:

assert: set a signal to its "active" state.

deassert: set a signal to its "inactive state.

If a signal is active-low, "asserting" that signal means setting it low and deasserting it means setting it high.

WRITTEN BY
RootFriend
개인적으로... 나쁜 기억력에 도움되라고 만들게되었습니다.

,
안녕하세요...

현재 PXA-255로 보드를 만들어 디버깅하는 중인데요..

저희 보드 스펙이 UART가 콘솔포함해서 7개거든요..

CPU 내부의 3개외에 여분의 4개 UART가 필요해서

4채널짜리 16C554 UART를 달았습니다..

어드레스는 554의 A0, A1, A2 에 각각 CPU의 A2, A3, A4를 붙였구요...

칩셀렉도 디코딩칩을 이용해서 충분히 넓은 어드레스 공간을 할당하였습니다..

drivers/char/serial.c 를 보니까 include/asm/arch/serial.h 파일안에 아래와 같이

PXA UART를 정의해주는 부분(STD_SERIAL_PORT_DEFNS)이 있고, 확장을 하려면

EXTRA_SERIAL_PORT_DEFNS 정의 부분에서 각각의 구조체 멤버에 값을 적용해주면 되는것 같은데요..

제가 궁금한 점은 아래와 같습니다...


1. serial.c 가 인터럽트 구동방식인가, 폴링방식인가??
~~ 소스가 넘 길어서 부분적으로만 분석했는데 아무래도 타이머가 돌아가는 것을 보니까
폴링방식같은데 실력이 딸려서 파악이 잘 안되네요..또 그와 더불어 인터럽트 방식이라면
구조체의 irq에는 무슨 값을 넣어야 하나요? 아래처럼 IRQ_GPIO_2_80 인가요? 아니면 다른 값인가요??
폴링방식이라면 irq의 값은 의미가 없는 값인가요??

2. PORT_DEFN 부분에서 xmit_fifo_size 에는 무슨 값을 넣습니까??
~~ 알기로는 pxa-255는 피포가 TX, RX 각각 64바이트로 알고 있는데 커널 소스에는 32로 되어 있군요..
16C554의 경우는 각각 16바이트인데...16을 써야 되나요? 아니면 CPU 처럼 반으로 나눈 8을 써야 되나요??

3. io_type 부분에는 무슨 값을 넣나요?
~~ SERIAL_IO_MEM32인가요? 아니면 SERIAL_IO_MEM인가요? 그와 더불어 iomem_base에는 무슨 타입을 써야 됩
니까?
저는 아래와 같이 u32로 하고 있는데 맞는지 확신이 안가네요..

4. serial.c 코드에서 뭔가 수정해야 할 부분이 있습니까??


어느정도 동작은 하는것 같은데...좀 불안해서요...
여기에 나와있는 시리얼 테스트 프로그램은 제대로 돌아가는데,
같은 채널의 TX와 RX를 붙여서 에코 테스트를 하니까 돌아가다가 송수신이 제대로 안됩니다..

쓰다보니 주저리주저리 많아진것 같네요...지루하셨다면 죄송합니다..
위의 사항에 대해 아시는 분이 계시면 알려주세요...
사소한 것이라도 괜찮습니다..

그럼..좋은 주말보내세요...

/////////////////////////////////////////////////////////////////////////////////////
#define TL554A_A (*((volatile u32 *) 0xf3000000)) // TL16C554A Ach virtual addr
#define TL554A_B (*((volatile u32 *) 0xf3100000)) // TL16C554A Bch virtual addr
#define TL554A_C (*((volatile u32 *) 0xf3200000)) // TL16C554A Cch virtual addr
#define TL554A_D (*((volatile u32 *) 0xf3300000)) // TL16C554A Dch virtual addr

#define STD_SERIAL_PORT_DEFNS \
{ \
type: PORT_PXA, \
xmit_fifo_size: 32, \
baud_base: BAUD_BASE, \
iomem_base: (void *)&FFUART,\
iomem_reg_shift: 2, \
io_type: SERIAL_IO_MEM32,\
irq: IRQ_FFUART, \
flags: STD_COM_FLAGS, \
}, { \
type: PORT_PXA, \
xmit_fifo_size: 32, \
baud_base: BAUD_BASE, \
iomem_base: (void *)&BTUART,\
iomem_reg_shift: 2, \
io_type: SERIAL_IO_MEM32,\
irq: IRQ_BTUART, \
flags: STD_COM_FLAGS, \
}, { \
type: PORT_PXA, \
xmit_fifo_size: 32, \
baud_base: BAUD_BASE, \
iomem_base: (void *)&STUART,\
iomem_reg_shift: 2, \
io_type: SERIAL_IO_MEM32,\
irq: IRQ_STUART, \
flags: STD_COM_FLAGS, \
},

#define EXTRA_SERIAL_PORT_DEFNS \
{ \
type: PORT_16550A, \
xmit_fifo_size: 16, \
baud_base: BAUD_BASE, \
iomem_base: (void *)&TL554A_A,\
iomem_reg_shift: 2, \
io_type: SERIAL_IO_MEM,\
irq: IRQ_GPIO_2_80, \
flags: STD_COM_FLAGS, \
}, { \
type: PORT_16550A, \
xmit_fifo_size: 16, \
baud_base: BAUD_BASE, \
iomem_base: (void *)&TL554A_B,\
iomem_reg_shift: 2, \
io_type: SERIAL_IO_MEM,\
irq: IRQ_GPIO_2_80, \
flags: STD_COM_FLAGS, \
}, { \
type: PORT_16550A, \
xmit_fifo_size: 16, \
baud_base: BAUD_BASE, \
iomem_base: (void *)&TL554A_C,\
iomem_reg_shift: 2, \
io_type: SERIAL_IO_MEM,\
irq: IRQ_GPIO_2_80, \
flags: STD_COM_FLAGS, \
}, { \
type: PORT_16550A, \
xmit_fifo_size: 16, \
baud_base: BAUD_BASE, \
iomem_base: (void *)&TL554A_D,\
iomem_reg_shift: 2, \
io_type: SERIAL_IO_MEM,\
irq: IRQ_GPIO_2_80, \
flags: STD_COM_FLAGS, \
}
/////////////////////////////////////////////////////////////////////////////////////

WRITTEN BY
RootFriend
개인적으로... 나쁜 기억력에 도움되라고 만들게되었습니다.

,

그냥 생각나는 대로, 손 가는 대로 작성해본다.

 

 

사실 통신회로 설계는 Data bus를 사용하지 않고 전용IC를 쓰기만 하면 매우 쉽다.

Datasheet에 있는 application 회로대로만 구성하면 누가 만들어도 대부분은 정상적인 동작을 하게 된다.

다만, 통신포트가 부족할 경우에 어쩔 수 없이 Data bus를 이용하는 85C30이나 68681 (단종된 것들이라 가격도 비싸고, 구하기도 어렵다), 16C550 등을 사용하는 경우는, 하드웨어나 펌웨어 양쪽에서 신경써야 할 것들이 좀 많아진다.

 

일단, RS232 통신은 기본적으로 3가닥의 선을 이용한다. TX line, RX line, GND... 이것만 제대로 연결하면 통신은 무조건 된다. 장담한다 ㅡㅡ

통신선로의 길이는 규격이 나와있지만, 사실 규격보다 더 길게 만들어도 동작한다. 물론, 통신의 정확성은 환경에 따라 달라지므로 장담하지 못한다는 것이 문제이긴 하지만... 실제로 쉴드케이블을 사용하고 RS232 라인을 늘려보았을 때, 50M 정도까지 통신이 되긴 했다. (그 이상은 안해봤다 ㅡㅡ)

뭐, 왠만하면 규격대로 하는 것이 속 편하긴 할 것이다. ㅡㅡ 나도 책임 질 생각은 없다. 누군가 해본다면 안된다고 뭐라고 하지 마라.

 

RS232 통신 전용 IC는 MAXIM 계열 칩들을 제일 많이 사용해봤다. 구하기도 쉽고... MAX3232나 MAX232 등등...

요즘엔 SP232를 더 많이 쓰긴 한다. Sipex 에서 나온 MAX232 호환칩인데, 가격이 더 싸다.

암튼... MAX든 SP든 232의 기본회로는 아래 그림과 같다.

 

 

IC 상단 좌측은 CPU와 연결되는 부분이고, 상단 우측은 외부로 나가는 부분이다. 하단 우측은 clock을 만들어주는 부분이다.

상단 좌우측은 그냥 연결시켜만 주면 끝이고 ㅡㅡ 하단 우측은 대부분 0.1uF 정도의 세라믹 캐패시터를 달아주면 끝이다. 쉽다 ㅡㅡ

Datasheet에 보면 C1~C4 까지 값을 바꿔서 넣어주라고 되어있긴 하지만... 그냥 몽땅 0.1uF으로 연결해도 지장이 없다.

 

뭐, 232를 왜 써야 하느냐에 대한 것들은 다른 블로그나, 자료가 많으니까 빼고...

 

CPU ---- MAX232 ---- 커넥터 =============케이블============== 커넥터 --- MAX232 --- CPU

 

이런 식으로 구성하면 되니까, 구성도 빼고...

 

위 구성대로 연결했는데 통신이 안된다~ 그러면 케이블 결선을 잘못했거나 확인해봐야 한다.

어느 한쪽의 TX line은 다른 쪽의 RX line과 붙어야 한다. (한쪽이 보내면, 다른 쪽은 받는 것이 당연하지 않겠나...)

가끔 GND 라인을 안붙이는 경우도 봤다 ㅡㅡ... GND 중요하다. 반드시 연결하자.

RS232는 3가닥만 있으면 통신은 한다. RTS, CTS 같은 신호선들은 기본적인 통신을 할 때는 전~혀 필요없다.

RX------------------------TX

TX------------------------RX

GND----------------------GND

 

MAX232에 전원을 인가하면, 통신을 하건 안하건 무조건 C3과 C4는 발진을 한다. 이녀석들이 발진을 하지 않으면 통신을 못한다.

이것도 중요하다. 이런 것들을 체크하지 않고 무조건 IC를 갈아보는 경우도 있더라... 돈 아깝다.

 

회로 설계의 기본이라고 해놓고... 써놓은 내용 보니까 아무것도 없다 싶다 ㅡㅡ;;; 제목을 바꿔야겠다 ㅡㅡ

 

COM 포트가 있는 PC에는 기본적으로 232 IC가 들어있다. PC에서 디버깅하려면 232 IC를 반드시 써야 한다.

(내가 처음 H/W 할 때 232 IC를 빼놓고 PC에 연결한 적이 있어서 안다 ㅡㅡ 통신 안한다)

 

 

내용이 별로 없으니... 16C554의 Uart 4 port에 각각 232 를 연결한 회로 하나만 보고 끝내자.

 

 

위에 필요한 신호들만 만들어서 연결해주면 된다. Data bus에서 Uart 포트 뽑아내는데에는 위 구성이 제일 좋다. 구하기 편하고 싸기 때문에 ㅡㅡ;;;



WRITTEN BY
RootFriend
개인적으로... 나쁜 기억력에 도움되라고 만들게되었습니다.

,
PXA255에 16c554이용해 UART확장 문의 드립니다..
우선 serial.c와 serial.h를 수정하여 아래와 같이
포트는 설정이 됩니다.. dmesg화면상에 아래와 같으 출력이 나옵니다.

Serial driver version 5.05c (2008-12-11) with no serial options enabled
ttyS00 at 0x0000 (irq = 14) is a PXA UART
ttyS01 at 0x0000 (irq = 13) is a PXA UART
ttyS02 at 0x0000 (irq = 12) is a PXA UART
ttyS03 at 0xf5010000x (irq = 41) is a 16C550
ttyS04 at 0xf5020000x (irq = 42) is a 16C550
ttyS05 at 0xf5030000x (irq = 43) is a 16C550
ttyS06 at 0xf5040000x (irq = 44) is a 16C550

문제는 실제 칩셀렉트가 안되고 있습니다.
가상주소에 대한 정의를 아래와 같이 하였습니다.
{ 0xF5010000, 0x16000000, 0x00010000, DOMAIN_IO, 0, 1, 0, 0 }, // CS5 : Serial CS1 A23:L, A24:L, A25:H
{ 0xF5020000, 0x16800000, 0x00010000, DOMAIN_IO, 0, 1, 0, 0 }, // CS5 : Serial CS2 A23:H, A24:L, A25:H
{ 0xF5030000, 0x17000000, 0x00010000, DOMAIN_IO, 0, 1, 0, 0 }, // CS5 : Serial CS3 A23:L, A24:H, A25:H
{ 0xF5040000, 0x17800000, 0x00010000, DOMAIN_IO, 0, 1, 0, 0 }, // CS5 : Serial CS4 A23:H, A24:H, A25:H

그리고 serial.h에서 확장 UART부분을 아래와 같이 정의하였습니다.

#define EXTRA_BAUD_BASE (3686400/16)
#define EXTRA_STD_COM_FLAGS (ASYNC_SKIP_TEST | ASYNC_LOW_LATENCY)

#define EXTRA_SERIAL_PORT_DEFNS
, {
type: PORT_16C550,
xmit_fifo_size: 16,
baud_base: EXTRA_BAUD_BASE,
iomem_base: (void *)&EXT_UART1,
iomem_reg_shift: 1,
io_type: SERIAL_IO_MEM,
irq: IRQ_UART1,
flags: EXTRA_STD_COM_FLAGS,
}, {
type: PORT_16C550,
xmit_fifo_size: 16,
baud_base: EXTRA_BAUD_BASE,
iomem_base: (void *)&EXT_UART2,
iomem_reg_shift: 1,
io_type: SERIAL_IO_MEM,
irq: IRQ_UART2,
flags: EXTRA_STD_COM_FLAGS,
}, {
type: PORT_16C550,
xmit_fifo_size: 16,
baud_base: EXTRA_BAUD_BASE,
iomem_base: (void *)&EXT_UART3,
iomem_reg_shift: 1,
io_type: SERIAL_IO_MEM,
irq: IRQ_UART3,
flags: EXTRA_STD_COM_FLAGS,
}, {
type: PORT_16C550,
xmit_fifo_size: 16,
baud_base: EXTRA_BAUD_BASE,
iomem_base: (void *)&EXT_UART4,
iomem_reg_shift: 1,
io_type: SERIAL_IO_MEM,
irq: IRQ_UART4,
flags: EXTRA_STD_COM_FLAGS,
}

#else
#define EXTRA_SERIAL_PORT_DEFNS
#endif


그런데.. 오실로 스코프를 찍어보면
실제CPU의 cs5가 활성화가 안되고 있습니다.
몇리째 삽질중인데..

조언부탁드립니다..
많이 어렵네요..ㅠㅠ

=================================================================================================================
이미 체크해보셨을 수도 있겠지만 혹시나해서...
cs5 의 어드레스 영역에 정상적으로 접근이 되는지 보셨나요?
아직 안해보셨다면 cs5 의 어드레스 영역에 읽고 쓰기가 정상적으로 되는지 mmap 같은 걸 이용한 간단한 프로그램을 돌리신 후에 오실로스코프로 확인해 보셔도 될 것 같은데요...
=================================================================================================================답변감사합니다..
CS5가 살지 않아
임의의 디바이스드라이버를 많들어 같은 가상주소와 같은 물리주소를주고
칩셀렉트가 되는지를 확인해봤습니다...


시그널 아주 잘 뜹니다.. 그래서 더 미치겠슴다..ㅠㅠ

WRITTEN BY
RootFriend
개인적으로... 나쁜 기억력에 도움되라고 만들게되었습니다.

,
안녕하세요
16c554 UART 칩 포팅관련하여 질문을 드립니다.
먼저 프로세서는 MPC8313 이며(POWER PC)
Linux 2.6.20 을 씁니다.

기존에 프로세서에서 지원하는 2개의 UART 를 썼는데,
UART 가 추가 로 필요하게 되어 16C554 칩을 쓰게 되었습니다.
16550 4개를 CS 4개를 통하여 제어한다고 생각하면 편합니다.
회로 연결은 Local BUS 에 칩의 Address ,Data,Irq 를 연결하였습니다.
그리고 Local BUS 의 OE,WE 을 칩의 Read,Write Enable 에 연결하였습니다.
그런데 기존 버전 2.4때에서는 Serial.h 에서
#define EXTRA_SERIAL_PORT_DEFNS
, {
type: PORT_16C550,
xmit_fifo_size: 16,
baud_base: EXTRA_BAUD_BASE,
iomem_base: (void *)&EXT_UART1,
iomem_reg_shift: 1,
io_type: SERIAL_IO_MEM,
irq: IRQ_UART1,
flags: EXTRA_STD_COM_FLAGS,
}, {
type: PORT_16C550,
xmit_fifo_size: 16,
baud_base: EXTRA_BAUD_BASE,
iomem_base: (void *)&EXT_UART2,
iomem_reg_shift: 1,
io_type: SERIAL_IO_MEM,
irq: IRQ_UART2,
flags: EXTRA_STD_COM_FLAGS,
}, {
type: PORT_16C550,
xmit_fifo_size: 16,
baud_base: EXTRA_BAUD_BASE,
iomem_base: (void *)&EXT_UART3,
iomem_reg_shift: 1,
io_type: SERIAL_IO_MEM,
irq: IRQ_UART3,
flags: EXTRA_STD_COM_FLAGS,
}, {
type: PORT_16C550,
xmit_fifo_size: 16,
baud_base: EXTRA_BAUD_BASE,
iomem_base: (void *)&EXT_UART4,
iomem_reg_shift: 1,
io_type: SERIAL_IO_MEM,
irq: IRQ_UART4,
flags: EXTRA_STD_COM_FLAGS,
}

#else
#define EXTRA_SERIAL_PORT_DEFNS
#endif

위와 같이 포트를 추가하여주었는데 2.6 에서는 어디에 추가 를 해야될지모르겠습니다.
추가 하는 곳만 알면 거기에 추가 해볼텐데 drivers/serial/8250.c 에 추가 해야하는건가여?
2.6 에 외부 Serial Port 를 어디에서 구조체를 선언해야되는지 아시는 분 도움좀 주세요~~
며칠째 씨름 하고 있는데~~너무 않되네여~~~꼭도와주세여~~~`!!


==============================================================================================================

Freescale 계열은 /arch/powerpc/boot/mpc8313erdb.dtd
파일을 수정해야할거같은데 너무 막막하네여
이 DTD 파일이 Kernel 보다 먼저 실행되는거같습니다.


WRITTEN BY
RootFriend
개인적으로... 나쁜 기억력에 도움되라고 만들게되었습니다.

,

** 2009. 6. 2   10:11 AM  추가

 

                1. reloc_start 실행 이후 call_kernel 까지는 정상적으로 진행

 

                2. call_kernel 에서 kernel entry point 인 0xA0008000 으로 점프 후 System hanging

                    (DEBUG 모드에서 0xA0008000 으로 점프 확인)

 

                3. 대체 뭐가 문제냐.......나도 지친다.....-_-;;

 

                4. 이젠 arch/arm/boot/compress/head.S 문제는 아닌데....보면 쳐 볼수록 짜증이 치솟냐....에휴;

 


  ** 2009. 6. 10 추가

 

............엄청 오랜만에 추가네;;

 

            1. 위의 문제는 부트 파라메터 오류로 인한 문제

                   - console=ttyS0,115600  =>  console=ttyS0,9600 으로 수정

 

            1.5. DMA 초기화 과정에서 system hanging 발생

 

                        pxa_dma_init() 에서 dma 레지스터 접근 시 그대로 system hanging

                        원인은 dma 레지스터의 주소를 어디서 찝적(겹칩)됬기 때문이라는데...

                        걍 dma 초기화 루틴을 수행하지 않도록 변경

 

                       ==> ethernet device(cs89x0) 에서 DMA 를 사용하긴 하지만, cs89x0.c 에서 ALLOWDMA 를 0으로 해버

                             리면 상관 없음. 시스템이 느려지긴 할테지만, 에러가 나진 않을 거 같음.

                               DMA 따위, 안쓰면 그만이지. 제기랄-_-;

 

            2. 이제 문제는 ethernet device 드라이버..

 

            3. ./driver/net/cs89x0.c 수정 작업 시작

 

            4. cs89x0 드라이버에서 접근할 가상 어드레스 0xF0000000 + 0x300 으로 설정

               (eth1 은 disable 시킴, 우선 하나만 되면 되지 뭐....)

               (eth1 의 가상 어드레스는 0xF2000000 + 0x300, IRQ 는 13)

 

           5. IRQ 는 0 으로 설정. IRQ_GPIO(0) 은 IRQ x is not in our map of allowable IRQs 발생시킴

 

  ** 4,5 번 내용은 모두 cs89x0.c 상에서 수정해야 하는 내용임!!

 

           6. 현재 기본 IP 설정까진 완료된 상태로 넘어가나... (192.168.1.101, 255.255.255.0)

 

                                        eth0: using half-duplex 10Base-T (RJ-45)

                                        IP-Config: Complete:

                                             device=eth0, addr=192.168.1.101, mask=255.255.255.0 gw=255.255.255.255

                                             host=192.168.1.101, domain=, nis-domain=(none),

                                             bootserver=192.168.1.100,

                                             rootserver=192.168.1.100,

                                             rootpath=,

 

           7. 아, 빼먹은건, u-boot 상에서 printenv 로 eth0, eth1 의 MAC address 확인하고, cs89x0 드라이버 상에서

             LUBBOCK 보드 선택 시 위의 MAC 주소를 강제로 입력하는 코드 추가해야 함

            (기본적으로 EEPROM 에서 읽어오는데, 없으므로, MAC address 를 만들어주어야 함)

              ==> u-boot 상의 MAC address 와 다르면, eth0: Failed to open eth0 가 발생함.

 

           8. Looking up port of RPC 100003/2 on 192.168.1.100

 

              여기서부터 오류 발생......NETDEV WATCHDOG: eth0 () : transmit timed out......얘는 대체 뭘까??

              스택 덤프 한번 해주고,

              rpcbind: server 192.168.1.100 not responding, timed out

              Root-NFS: unable to get mountd port number from server, using default

              eth0: transmit timed out, IRQ conflict ??          <== 뜬금없는 왠 IRQ conflict....

 

              그 다음은 VFS 오류 후 당연한 Kernel panic...

 

         ==> 이걸 eth0 설정은 다 된거지만, NFS 설정을 잘못해서 난 오류로 봐야할까 아니면 eth0 가 안잡힌 걸로 봐야할까....그런데 IP 설정이 제대로 된걸 보면 eth0 가 안잡혀서 그런거 같진 않은데...애매하다. 지금은 계속 이거 알아보는 중.

 


'Embedded > Xhyper255A' 카테고리의 다른 글

Android porting to XScale PXA255  (0) 2009.06.16
kernel error  (0) 2009.06.08
[답글]255A보드에서 GPIO제어.  (0) 2009.06.08
[답글]X-Hyper255A에서 커널에 대해...  (0) 2009.06.08
[XHYPER255] 커널 2.6 컴파일  (0) 2009.06.05

WRITTEN BY
RootFriend
개인적으로... 나쁜 기억력에 도움되라고 만들게되었습니다.

,

---------------------------------------------------------------------------------

 * Enviroment

---------------------------------------------------------------------------------

  Host Platform      :  Ubuntu 9.04, i386

  Target Platofrm   :  Corebell LDS2000 (PXA255)

  Cross Compiler  :  - Android bulit-in arm-gcc (EABI)

                                    - Codesourcery arm-gcc toolchain

---------------------------------------------------------------------------------

 


 

1. 기존 LDS2000 의 2.4.19 kernel 에서 lds2000.c / sa1111.c 를 2.6.27 로 포팅 후 컴파일

 

      - Kernel 로딩부터 무응답

      - Trouble 을 발생시킨 이유를 알 수 없어 패스

 

2. Android 지원 Platform 인 Intel DBPXA 255 (lubbock.c) 에 lds2000.c 의 메모리 맵 정보를 옮겨 컴파일

 

      2.1  Uncompressing kernel image...   => hanging -_- 

      

                - TFTP 로 load 하는 위치 (address) 변경   =>    Kernel 시작 실패

                                                                                            =>    Bad magic number

 

                - Kernel Image 의 Load / Entry Point 변경  =>    Bad gzipped data

                                                                                            =>    Out of memory (in uncompressing)  이어지는 System halt

 


** head.S  -> misc.c  -> piggy 로 이어지는 과정 추적

 

1. head.S 시작 후 decompress_kernel 함수 호출, 여기서 gunzip() 수행 시 에러 발생

 

        - out of memory 또는 prefetch abort, 아니면 아예 대답없는 빌어먹을...

 

2. gunzip() 함수를 수행하지 않도록 주석 처리

 

        - 역시나 예상을 빗나가지 않는 prefetch abort....

 

3. piggy.gz 의 압축을 풀고, decompress_kernel 을 패스 한 후 바로 piggy 로 부팅 시도

 

        - 역시나 당신은 대답없는 개자식...

 

 


** Google 에서 u-boot gunzip hanging 으로 검색

 

               1.  SVN r44, Intel SDRAM

 

                            - u-boot 에서 Intel SDRAM 의 Refresh rate 가 너무 낮게 설정되어 drop 되는 bit 발생

                            - Refresh rate 를 수정하고 정상 작동 되었다 함

 

                2. Gumstix 보드에서의 gunzip hanging

 

                            - 1번과 유사한 문제로 추정.

                            - 한놈은 inflate 함수에서 delay 를 통한 지연으로 낮은 Refresh rate 를 넘김

                            - 다른 한놈은 CPU Memory rate 조작으로 해결

 

                        * delay 적용 해 봤지만............역시나. 아아, 이 아름다운 개색히.

 

                 3. gzip 의 문제.

 

                             - gzip 사용시 이놈도 계속 uncompressing 중 hanging

                             - bzip, bzip2 등을 이용하여 압축 시 uncompressing 중 hanging 이 발생하지 않았다 함

                             

                        * 될지 않될지도 모르는 bzip2 패치 언제 하고 앉았냐....-_-

 

 


** head.S

 

                 1. 2.4.19 Kernel 의 head.S 가지고 해봐도 실패

 

                 2. 인터넷에서 구한 head.S 가지고 해봐도 실패 (꽤 예전걸로 보임)

 

                 3. 어떤 head.S 든 uncompressing 중 hanging  /  prefetch abort  /  out of memory 로 이어지는 크리...

 

                 4. 결론은 주소 값이 뭔가 잘못 지정되었다는 건데.........(head.S - 12월 32일. (feat. 과제 제출 날짜))

 

 


** 특이점

 

                1.  misc.c 의 decompress_kernel() 함수에서 gunzip() 함수의 콜을 주석 처리 했을 때에는

                   decompress_kernel()  의 인자로 넘어오는 커널 시작 포인트가 Makefile.boot 에서 지정한 것과

                   동일한 주소가 넘어옴

                      그러나 gunzip() 함수 수행시, Makefile.boot 에서 지정한 zreladdr-y=0xA0100000 과 다른 주소값이

                   넘어옴. 어떤게 맞는 건지 아직은 모르겠다. 젠장.

 

                2. 아무래도 주소 문제인 것 같은데...커널이 시작이라도 되는 양반들은 안드로메다에서 오신건가?

 

                3. Kernel Image 의 크기는 990KB,  약 1MB, 따라서, TFTP 로 0xA0000000 으로 로드하면 1MB 뒤는

                   0xA0100000 이므로 Load / Entry Point 를 0xA0100000 으로 잡았는데....이게 문제인가...

 

 

                   이거 보면....0xA0008000 에 Load / Entry Point 를 잡을 경우, Kernel Image 가 씹히게 되는데....

                   설마 gunzip() 함수 라이브러리가 문제 있는건 아닐테고....

                   (구글 뒤져봐도 이게 잘못됐다는 소리는 없고....게다가 현재 라이브러리는 최신....니미럴)

 


** 중간결산

 

                1.  Kernel 이 시작 되도 손봐야 할게 한두군데가 아닌데....기한내에 할 수 있겠니;;;;;;

 

                2.  정 않되면 bzip2 패치도 하고, u-boot 에서 RAM refresh rate 조정 해서 다시 올리고...

                    (어느 세월에................엿먹을 안드로이드, 신의 저주 있으라-_-니미)

 

                3.  Kernel 이 시작이라도 하는 양반들은 안드로메다 행성에서 오신거임. 

 

 


** 2009. 6. 1 추가

 

                1. gunzip 의 문제가 아닌 Relocation Code 를 압축 해체된 커널 이미지 뒤로 copy 하는 부분에서의 문제

 

                2. Debugging 자료

 

                       - decompressed kernel length : 0x001E02B0  (1.9MB, 압축전 piggy의 크기는 1.9MB, 따라서 정상)

                       - 압축 해제는 정상적으로 진행된 것으로 판단

                       - reloc_start address : 0xA01003C0

                       - reloc_end address :  0xA01007B0

                       - relocation code length : 0x03F0 = 1008 bytes

                             => 1008 bytes 의 경우, ldmia 명령어로, 6개 register 로 읽어오면, 1008 / 24 = 42,

                                   ldmia, stmia 를 42회 반복해야 함

                             => 원래 코드에서는 단 2회 반복

                             => 이것으로 볼 때, reloc_start 부터 call_kernel 이전 까지만 옮긴다고 생각 할 수 있음

                             => 그럼 call_kernel 을 비롯한 뒤의 나머지들은 어쩌라는겨??????

                             => 최소한 call_kernel 까지는 옮겨야 커널 시작점이 발생된다고 생각하는데....

                             => reloc_start + call_kernel 은 대략 96 bytes, 따라서, ldmia, stmia 최소 4회 반복해야 할 것인가?

                             => 2009. 6. 2 수정.  루프 구간이였다. 48 bytes 씩-_- 멍청하긴;;

 

                       - arch/arm/boot/compressed/head.S (line: 264)

 

                                          bl            decompress_kernel
                                          add         r0, r0, #127 + 128                     @ alignment + stack
                                          bic           r0, r0, #127                                @ align the kernel length
                                          /*
                                           * r0     = decompressed kernel length
                                           * r1-r3  = unused
                                           * r4     = kernel execution address
                                           * r5     = decompressed kernel start
                                           * r6     = processor ID
                                           * r7     = architecture ID
                                           * r8     = atags pointer
                                           * r9-r14 = corrupted
                                           */
                                           add        r1, r5, r0                                @ end of decompressed kernel

                                  /**  r1 : 압축 해제된 kernel image 의 끝 위치 (address)  : 0xA03E6CAC*/
                                           adr         r2, reloc_start

                                  /**  r2 : reloc_star 의 위치 (address, 압출 풀린 kernel image 의 relocation code 

                                             : 0xA01003E0  */ 
                                           ldr          r3, LC1

                                  /**  r3 : LC1 (reloc_end - reloc_start), reloc_start 의 코드 길이 : 0x000003F0 */
                                           add        r3, r2, r3

                                  /**  r3 : reloc_end 의 위치 (address) */
                               1:         ldmia    r2!, {r9 - r14}                        @ copy relocation code <== 여기서 시스템 패닉!!!!!!!
                                           stmia    r1!, {r9 - r14}
                                           ldmia    r2!, {r9 - r14}
                                           stmia    r1!, {r9 - r14}

                                   /** r9 - r14, 6 개 register, 길이는 6 * 4 bytes = 24 bytes 

                                        reloc_start 를 24 bytes 씩 읽어서, 압축 해제된 kernel image 의 뒤로 reloc_start 를 이동

                                        따라서 총 48 bytes 이동 */                                        
                                           cmp      r2, r3
                                           blo        1b
                                           add       sp, r1, #128                       @ relocate the stack

                                           bl          cache_clean_flush
                                          add        pc, r5, r0                             @ call relocation code <== 이동시킨 relocation code 수행

 

 

 

                3. 유사한 문제점들

 

                       - KELP(kelp.or.kr) 에서 s3c2800 포팅 시 상기 문제와 동일한 문제 발생 확인

                       - 최초 작업 시 ldmia, stmia 한번 더 수행하므로서 해결

                       - 실제 release 에서는 저 부분이 삭제 됨 (원래 코드로 수행)

                       - 실제는 하드웨어와 부트 로더 문제였으며, 그 둘을 수정함으로써 해결했다함

 

 


** 중간결산2

 

                1. 위에 gunzip 문제와 같이, 결론적으로는 부트로더를 손봐야 한다는 결론에 도달

 

                2. 그럼 대체 부트로더 수정없이 커널 도는 양반들은 진짜 안드로메다에서 온거냐?????????

 

                3. 어느 세월에 부트로더 수정하고 있냐....어디 수정해야 할지도 모르는데....염병-_- 

 

                4. 그런데 이상한건....relocation code 복사하고 나서 call_kernel 이 씹히는 바람에 시스템 패닉은

                   이해가 된다지만....대체 왜 LDMIA r2!, {r9 - r14} 에서 시스템 패닉이 일어나냐는 거다.

                   이건 정말 희한한 문제란 말이지.......

 

                5. LDS2000 에서의 RAM 영역은 0xA0000000 부터 0xA4000000 인데...메모리 영역이 잘못 잡힌것도

                   아니고..........답이 없다 썅-_-

 

 

 


** 2009. 6. 2   05:30 AM  추가

 

                1. 위에 추가한 문제로 시스템 패닉 아닌 것으로 판명됨

 

                2. LDMIA 에서의 시스템 패닉은 bl  print_reg_value 를 호출하는 과정에서 다른 레지스터의 값이

                   변경되므로써 발생하는것으로 확인

 

                3. 따라서 레지스터 값을 저장/복구 시켜가며 확인한 결과 call_cache_fn 에서

                   old ARM ID (value: 0x00000000) 에 걸리면서 System hanging 이 발생한 것으로 확인

 

                4. call_cache_fn 에서는 각 CPU 타입마다 서로 다른 mmu_cache 함수를 호출하는데,

                   make menuconfig 에서 PXA2xx/3xx -> LDS2000, 또는 LUBBOCK 선택 시 CPU_PROCESSOR_ID

                   값이 설정되지 않음

 

                5. 이로 인하여 적절한 mmu_cache 함수를 선택하지 못하고 무한루프 / prefetch abort 발생

 

                6. XScale PXA-255 는 ARMv5TE 에 포함되므로 이것으로 CPU_ID 값을 변경하도록 함

 

                7. ((real_id ^ match value) & mask) == 0 인 경우 같은 것이므로,

                               ldr      r6, =CONFIG_PROCESSOR_ID

                        대신, ARMv5TE 의 match value 인 0x00050000 값을 대입

                               ldr      r6, =#0x00050000

'Embedded > Xhyper255A' 카테고리의 다른 글

Android porting to XScale PXA255 (2)  (0) 2009.06.16
kernel error  (0) 2009.06.08
[답글]255A보드에서 GPIO제어.  (0) 2009.06.08
[답글]X-Hyper255A에서 커널에 대해...  (0) 2009.06.08
[XHYPER255] 커널 2.6 컴파일  (0) 2009.06.05

WRITTEN BY
RootFriend
개인적으로... 나쁜 기억력에 도움되라고 만들게되었습니다.

,

가끔 질문이 올라 온 내용 중 하나인, rs-232c 포트를 atmega128에서 지원하는 2개 이상 사용하기에 대한 답을 한번 정리 해 봤습니다.

 

RS-232 통신 포트의 수를 늘리고 싶다면?
1. MCU 를 바꾼다.
2. Software 적인 Serial 통신을 구현한다.
3. TL16C554 같은 Full duplex, buffer 를 지원하는 전용의 IC를 사용한다.
4. I2C/SPI  RS-232c 를 구현하던가, 아니면 IC를 구해 본다.
5. MAX399 같은 MUX를 사용한다.

 

1. atmega 128의 상위 모델 중 atmega640, atmega1280, atmeg2560등은 4개의 serial uart(rs-232c)를 가지고 있다.

    단 MCU가 100핀 짜리라는 단점이 있다.  현재 실컷 128 등으로 작업을 한 상태라면 처음부터 다시 시작해야 한다는 슬픔이 있다.

 

2. GPIO를 이용하여 소프트웨어 적으로 rs-232 통신을 구현할 수 있다.

관련된 자료로는 Procyon Library에 포함되어 있는 uartsw.c 또는 uartsw2.c  를 참고 하기 바란다.  또한 이 방식은 comfile社에서 판매하고 있는 PIC basic 제품군에서도 사용하고 있는 방법이다. 하지만 이것 또한 인터럽트 방식으로 사용할 수 없으며, 한 개의 byte를 받는 과정에서도 데이터를 정확히 받을 수 있다는 보장이 없다. 예전에 Serial Pic’n 이라는 PIC mcu의 책에서도 이 방법에 대한 설명과 어셈블리 소스가 있었다. 책을 팔고나니 볼 일이 생기는 것 같다.


 

3. TL16C554는 4개까지 시리얼 포트를 확장할 수 있으며, 내장 FIFO(16byte)와 함께 Flow Control 까지 가능하다.

이 IC를 사용하는 것이 가장 정석적인 방법이지만, 사용방법이 쉽지는 않다. 예전에 도스 시절에 직접 RS-232c 포트 프로그램을 작성 하던 때가 생각이 날 정도다. 또한 address mapping방식으로 이 IC를 연결해야 한다. 그래서 외부 주변장치들과 mcu와의 연결을 GPIO를 이용하여 연결했다면, 설계를 다 바꿔야 할 지도 모른다.  이런 용도의 IC들은 uart의 개수, FIFO의 크기 등에 따라서 다양한 모델이 있으므로, www.ti.com  에서 “TI Home > Interface > UARTs “ 에서 찾아 보기 바란다.

또한, EXAR(www.exar.com)에서도 이런 기능의 IC를 판매하고 있다. 전자기술 2004년 8월호에 이 EXAR 의 ST16C2550을 사용하여 설계하고 프로그래밍을 하는 기법에 대한 기사가 있다.

 

4. I2C/SPI <=> RS-232 ic 를 사용한다.
이 방식은 예전에 본인도 한번 구상을 했었다. AVR, PIC을 이용해서 프로그램을 잘 짜면 되지 않을까? 라고 생각을 했는데,

하지만 AVR을 사용할 경우 한가지의 문제가 있는데 하드웨어에 구현한 FIFO 가 없어서 full duplex가 가능할 것 같지 않다는 것이다. EXAR社의  XR20M1170 라는 제품은 하드웨어에 rs-232용의  64byte 양방향 FIFO가 있는데,

1) 부품을 구할 수 있을 지 ? 2) 동작 전압이 1.62~3.3V 라서 5V용의 MCU와의 연결을 위해서는 각 신호 선들의 level을 바꿔주어야 하는 단점이 있다.

 

5. Mux 를 사용
예) MAX399 :: http://www.fh-augsburg.de/~hhoegl/proj/rs232-mux/300.html 
 


이 방법은 현재 선택되어 있지 않은 포트에서 데이터가 들어 올 경우, 데이터를 잃어 버릴 수 있다.  하지만, rs-232로 데이터를 내보내기만 할 경우에는 유용하게 사용할 수 있다.

WRITTEN BY
RootFriend
개인적으로... 나쁜 기억력에 도움되라고 만들게되었습니다.

,
시리얼 관련해 흔히 혼동하는 부분('Debug Port', 'UART', 'Serial', 'COM')에 대해서 자료를 찾다가 좋은 문서가 있어서..

먼저 UART는 Universal Asynchronous Receiver/Transmitter로서 CPU에 붙어있는 interface이다.
URAT0, UART1, ...등으로 얘기를 많이 하고, Data 통신을 RS232와 같이 RX/TX serial하게 하기 때문에 보통 시리얼 포트라고 한다.
RS-232는 보통 컴퓨터에 붙어있는 connector이름이다.

시리얼(Serial)은 응용프로그램과 드라이버간의 인터페이스를 이야기하는 것으로, 시리얼 디바이스 드라이버라고 한다.  UART 포트를 사용할 수 있는 드라이버..
응용프로그램은 UART포트가 0인지 1인지2인지를 알 수가 없다. 그래서 *.reg파일에 index를 할당하여COM의 번호를 할당해 준다.

COM은 UART의 Driver가 OS로 올라갈 때 COM이라는 이름으로 올라가는 것이다.

디버그 포트(Debug Port)는 OS에서 Debug용도(개발 보드에서 디버깅을 하기 위한 용도)로 사용하기 위해 설정하는 것이다. 흔히 하이퍼 터미널과 같은 것으로 부팅이나 프로그램 실행시 메시지를 확인하는 것이 디버깅 포트이다.

디버그 포트는 디바이스 드라이버가 올라가기 전부터 통신을 해야한다. 그래서 디버그 포트와 관련된 구현은 EBOOT, KERNEL쪽에 구현이 되어있다.

중요한 점은 Debug port와 UART의 driver가 같은 포트를 사용하게 되면 충돌이 일어나게 된다.
Debug port로 사용할 경우 UART를 사용할 수 없다는 말이다.

WRITTEN BY
RootFriend
개인적으로... 나쁜 기억력에 도움되라고 만들게되었습니다.

,
- uart and spi 모두 시리얼통신방식이다.

- uart는 타겟과 타겟이 조금 떨어져 있을때

- spi는 보드내에서 다른 주변장치와 통신할때

- SPI의 경우는 만들 당시 부터 주변 부품에 대한 연결을 목적으로 만들어졌다고 합니다. 그래서 여러개의 슬레이브를 선택 할수 있고요. 마스터에서는 /Slave Select 단자를 사용하거나 GPIO를 이용해 슬레이브의 /CS 단자를 제어함으로써 여러개의 부하를 호출하여 데이터를 주고 받는 구조로 되어 있습니다. 그리고 속도는 2~3Mbps정도까지도 가능하고요.

- 기준 클럭에 데이터가 실리느냐 아니면 기준클럭 없이 서로 각자 시간만 맞추고 알아서 주고 받느냐...
역 시 비동기식과 동기식의 차이겟죠... 역시 기준클럭이 필요한 동기식(spi)의 경우는 기준 클럭과 데이터가 서로 씽크가 안맞는다면, 데이터 자체가 영향을 받기 때문에 비교적 전송 거리가 짧은 통신에 사용하죠. 그래서 주변 디바이스 인터페이스에 사용합니다. 그래서 아마도 Serial Peripheral Interface의 약자일껍니다

[출처] uart와 spi의 차이점 |작성자


WRITTEN BY
RootFriend
개인적으로... 나쁜 기억력에 도움되라고 만들게되었습니다.

,