Linux2017. 2. 27. 10:52

vi 관련 환경설정 파일을 만든다.


1. 터미널에서 사용자 계정으로

vi ~/.vimrc


2. 다음 내용을 추가

:set nocompatible


3.저장

Posted by 십자성군
TMS320/F283352017. 2. 22. 04:38

DSP 디버깅에서 확인한 프로그램을 MCU에 업로드할 경우, 기본적으로 제공되는 예제와 같이 flash 영역에 기재할 경우 ROM 영역에서 돌아가는 프로그램은 전체적으로 속도가 느리다. 따라서 디버깅때와는 달리 프로그램이 제대로 돌아가지 않는 경우가 많다.


이를 해결하기 위해서 (1)중요한 변수나 함수영역의 일부를 ram 영역에서 구동하는 방법이 있지만, 코드의 규모이 비교적 소규모이고 전체적으로 디버깅때와 같은 처리속도가 필요하다면, 아예 (2)모든 code를 ram 영역으로 옮기는것도 한 방법이다.


(1)의 방법으로는 일일이 선언해줘야 하는 문제도 있기 때문에 본인으로써는 왠만하면 (2)의 방법을 추천한다.

또한 DSP28377의 경우 ram 영역의 크기가 28335의 3배에 가깝기 때문에 코드의 규모가 비교적 크더라도 적재할 수 있다.


이번 글에서 설명할 것은 코드의 규모가 큰 경우를 위한 메모리 배치와 flash programming이다.

아래는 메모리 배치의 cmd파일의 내용이다. 어느정도 cmd 파일을 건드려 보았다는 전제하에 자세한 설명은 생략한다. 또한 앞글의 reference를 반드시 먼저 확인하기 바란다.


1.



2.


3.


주의해야할 영역은 .stack영역이다. 이 영역은 RAMM0, RAMM1, RAMD0, RAMD1 영역등이 반드시 포함되어야 한다. 그렇지 않을 경우 프로그램을 실행하였을 때 에러관련 인터럽트가 걸려 에러함수에 진입한다.


그 외에 .cinit, .pinit, .econst, .switch 는 GSxRAM을 사용할 수 있다. .text또한 GSxRAM을 사용할 수 있다.


보통 프로젝트를 설계할 때 .text와 .stack 영역의 메모리가 부족한 경우가 종종 발생한다. .stack의 경우 변수 및 함수를 포함한 정적 메모리할당이 관련하며, .text는 프로그램 코드 자체의 크기에 관여한다. 즉, 프로젝트의 소스 규모가 크면 클수록 .text와 .stack이 요구하는 메모리가 커진다고 할 수 있다.


메모리 영역을 공유하여도 되지만 어차피 28377이 제공하는 RAM 영역이 꽤나 크기 때문에 공유하는 일 없이 배치해주었다.


4.


ramfuncs는 (1)방법에서 사용되는 영역이기 때문에 FLASH 영역만 배정하였다. 이 영역을 쓸 일은 없을것이다.



//--------------------------------------------

아래는 플래시 작업을 위해서 변경해야할 파일들이다.


DSP28xxx_SectionCopy_nonBIOS.asm

F2837xD_CodeStartBranch.asm

2837xD_FLASH.cmd

F2837xD_usDelay.asm

F2837xD_SysCtrl.c


DSP28xxx_SectionCopy_nonBIOS.asm 파일은 위에서 선언한 RAM영역에의 메모리 배치를 수행하는 어셈블리어가 짜여있다.


저 위의 파일들을 변경하는 것으로 28377의 디버깅모드로 사용하던 DSP를 동일한 성능으로 stand alone 모드로 사용할 수 있다. 변경전에 디버깅모드로 사용하던 당시의 파일들을 백업하는 것을 잊지말자.


※참고

flash 프로그래밍을 한 이후에 No source available for 어쩌구 하는 로그가 뜰 때가 있습니다.

이 때 디버깅의 진행버튼(> 버튼)을 눌렀을 때 진행이 된다면 아무런 문제가 없는 것입니다.

저의 경우 No source available for "0x3fe493" 라는 로그가 떴습니다.

0x3fe493 이라는 주소는 메모리맵을 참조했을 때 Boot ROM 영역에 있는 주소입니다.(Boot ROM은 0x3F8000~0x3FFFBF 영역을 차지합니다.)

이는 저희가 사용하는 ccs로는 boot rom 영역에 대한 디버깅을 할 수 없기 때문입니다. 이는 DSP의 부트롬 영역에 내장되어 있는 부분이니 저희가 건드릴 일은 없으니 걱정하지 않으셔도 됩니다.

단, 위 로그가 뜬 후에 진행버튼(> 버튼)을 눌렀는데도 프로그램이 진행되지 않는다면 cmd파일에서 메모리를 잘못 배치한 부분이 있을 수 있으니 원인을 알아보시기 바랍니다.


제가 고생한 만큼 이 글을 참고하시는 분들께 도움이 되기를 바랍니다

'TMS320 > F28335' 카테고리의 다른 글

DSP28377x D와 S의 SRAM 차이  (0) 2017.05.12
DSP 28335, 28377 flash 작업을 위한 기본자료  (0) 2017.02.22
DSP28335 Flash programming  (0) 2017.02.19
ePWM 설정  (0) 2017.02.09
DSP 프로젝트 생성(28377, 28335 공통)  (0) 2016.11.21
Posted by 십자성군
TMS320/F283352017. 2. 22. 04:32

DSP 28335 관련


TMS320F28x CPU이해.ppt

tms320f28335.pdf




//-----------------------------------------------

DSP 28377 관련


Datasheet_F28377D-176_M_V100.pdf

Running an Application from Internal Flash Memory.pdf

Copying Compiler Sections From Flash to RAM.pdf



'TMS320 > F28335' 카테고리의 다른 글

DSP28377x D와 S의 SRAM 차이  (0) 2017.05.12
DSP 28377 Flash programming on ram sections  (8) 2017.02.22
DSP28335 Flash programming  (0) 2017.02.19
ePWM 설정  (0) 2017.02.09
DSP 프로젝트 생성(28377, 28335 공통)  (0) 2016.11.21
Posted by 십자성군
기타/문제해결기2017. 2. 22. 03:59

DSP 28377을 사용하면서 겪은 문제입니다. DSP에 한정되지 않고 다른 MCU를 사용하는 와중에도 발생할 수 있는 문제입니다.


DSP와 CC3200이라는 MCU사이에서 시리얼 통신을 하도록 하였습니다. 아래의 사진은 CC3200으로 로그를 확인한 것입니다.


CC3200으로 WiFi에 접속하여 인터넷을 사용할 수 있는데, Received Contents에 HEX값으로 데이터가 마구 들어와 있습니다.

이는 DSP에 코드를 다운로드 하는 와중에 발생한 문제입니다.

본래는 정상적으로 데이터를 수신해야 하지만 DSP에 프로젝트를 다운로드 할 때, 연결된 SCI 주변 센서에 쓰레기값을 마구마구 전송합니다.


첫번째 for문은 DSP에서 특정한 정보를 보내기 위해서 SCI버퍼에 송신 데이터를 넣는 방법과, 따로 함수를 사용하는 방법을 시험해 봤습니다. 당연한 것이지만 어떻게 하느냐에 따라서 센서가 데이터를 수신하기도 하고 못하기도 합니다. 시리얼 통신을 할 때는 데이터와 데이터 사이에 약간의 딜레이가 있어야 하는듯 합니다.


프로그램을 플래시모드로 돌린다면 문제 없겠지만 개발도중에는 디버깅 모드를 사용할 수 밖에 없기 때문에 CC3200에서 쓰레기값을 확인할 수 있게 하여야 합니다. 가끔씩 쓰레기 값인데도 형식에 맞는 데이터가 와서 곤란할 때가 있습니다.

특히 MCU가 메모리를 다루는 작업을 할 필요가 있을 때 조심해야 합니다. 위 사진은 프로토콜을 읽어서 데이터를 복사하는 부분인데, 쓰레기 데이터에 대한 처리를 잘못해서, 메모리를 마이너스 길이로 복사하게 해버렸습니다. 게다가 MCU에서 try, catch를 사용할 수 없게 해놨었기 때문에, 애초에 문제가 발생하지 않도록 해야 했습니다.


위 코드는 모터를 돌리기 위한 코드입니다. DSP28335에서 C++기반으로 코드를 짰다가 28377에 옮길 때, C++에서 너무 오작동을 많이 하기에 C코드로 변경했습니다. 그래도 함수는 그대로 사용했기 때문에 정상동작을 해야 했습니다만...


mTempMl = vPWM.pLeft 와 같이 그저 값을 복사 후 조건문을 사용해서 값이 음수면 양수로 바꿔주면서 방향에 대해 1, 0을 넣어주는 코드일 뿐인데, 28377에서는 제대로 동작 안하더군요. vPWM이라는 인자의 값 까지는 정상적으로 들어오지만 조건문을 거쳤을 때, mTempMr과 mTempMl의 값이 달라야 하는데 항상 서로의 값이 같아지는 현상이 발생했습니다. 코드 오류는 없었구요.


컴파일러가 어떻게 되어있길래 저런 문제가 발생하는지는 모르겠더라구요. 결국 인자로 받았던 vPWM의 값을 조건문에 넣었더니 해결되었습니다. 컴파일러의 문제이거나 DSP의 Code optimization 과정에서 발생한 문제일 수도 있겠습니다.



Posted by 십자성군
TMS320/F283352017. 2. 19. 00:40


플래시 관련 자료를 압축해서 올립니다.

관련 문서.zip


아래는 결과적으로 RAM, FLASH 변경할 때 바뀌는 파일들입니다.(개인적으로 수정이 되어있습니다.)

flash.zip

ram.zip


참고로 이번 자료에서 사용하는 방법은 flash에 들어가야 하는 프로그램을 RAM에 모조리 load해서 프로세스를 빠르게 운행하는 것입니다. 이는 사용하는 DSP의 내부 RAM의 용량이 충분하거나 프로젝트가 소규모일 때 사용하는 방법입니다.


내부 RAM의 용량이 작거나 프로젝트의 규모가 클 때는 전체 프로그램이 아니라 일부 함수만 RAM에 올리는 방법을 사용한다고 합니다.

'TMS320 > F28335' 카테고리의 다른 글

DSP 28377 Flash programming on ram sections  (8) 2017.02.22
DSP 28335, 28377 flash 작업을 위한 기본자료  (0) 2017.02.22
ePWM 설정  (0) 2017.02.09
DSP 프로젝트 생성(28377, 28335 공통)  (0) 2016.11.21
Baudrate 설정  (0) 2016.10.09
Posted by 십자성군
기타2017. 2. 16. 05:24

DSP등을 사용하면서 UART데이터를 보내려고 할 때, 이를 위한 전용의 함수를 만들어서 사용하곤 한다.



예를들면


typedef volatile struct SCI_REGS RSCI, *PRSCI;


void sci_xmit(const PRSCI pChannel, const unsigned char b);

void ArrayTransmit(const PRSCI pChannel, const unsigned char* Array, const unsigned int length);


void sci_xmit(const PRSCI pChannel, const unsigned char b){

while(pChannel->SCICTL2.bit.TXEMPTY == 0){}

pChannel->SCITXBUF.all=b;

}


void ArrayTransmit(const PRSCI pChannel, const unsigned char* Array, const unsigned int length){

unsigned int i=0;


for(i=0; i<length;i++){

while(pChannel->SCICTL2.bit.TXEMPTY == 0){}

pChannel->SCITXBUF.all=Array[i];

}

}


위 코드는 내가 DSP 28335나 28377 에서 시리얼데이터를 보낼 때 사용하는 함수이다.

위와 같이 사용하면 SCI관련 레지스터의 포인터를 보내는 것으로 어떤 SCI 채널에서든 사용할 수 있다.


그런데 사용 도중 문제가 발생하였다. A와 B센서를 사용하고 이와 통신할 때, 처음에는 함수가 잘 동작하였었는데 프로젝트의 규모가 커지고 코드가 많아짐에 따라 B센서에 데이터가 잘 보내지지 않는 것이다.


당시 전송을 위해서 아래와 같은 코드를 사용했다.


BOOL Write(const PRSCI pChannel, const BYTE* data, const DWORD dataLength){

if(!data || dataLength <=0)

return FALSE;


if(pChannel == 0)

return FALSE;


const DWORD EOI = dataLength/2;

BYTE TXData = 0;

DWORD i = 0;


for(i=0; i<EOI; i++){

TXData = data[i];

sci_xmit(pChannel, (TXData&0x00ff));

sci_xmit(pChannel, ((TXData&0xff00)>>8));

}


return TRUE;

}


DSP에서는 자료형의 최소단위가 2byte였는데, 문자열을 보내는것이 아니라 byte데이터를 보내야 했기 때문에 2byte데이터에 대해서 위처럼 bit shift를 활용해야 했었다. 데이터가 정상적으로 센서에 전송이 되면 센서는 응답을 보내는데 당시 DSP의 수신기능에는 전혀 문제가 없었다.


이것저것 시험해본 결과 깨닫게 된 것은 데이터 전송에 있어서 함수호출방식을 사용했다는 것에 문제가 있다는 것이다. 저 sci_xmit함수를 한번 호출하는데 적어도 다음과 같은 과정을 거칠것이다.


1. 함수의 주소를 참조하여 함수를 호출한다.

2. 두개의 인수 pChannel과 데이터를 넣어준다.

3. 호출된 함수 sci_xmit에서 두 인수가 복사된다.

4. while에서 전송용 버퍼가 비워질 때 까지 기다린다.

5. 전송하고 return한다.


프로젝트 규모가 작았을 때는 센서 B에서 문제없이 응답이 돌아왔었는데 프로젝트가 커지더니 응답이 돌아오지 않았다. 디버깅모드에서 전송 행위는 정상적으로 이루어졌다고 보였었다.


여러가지 방법을 시도하다가 sci_xmit의 while문(버퍼가 비워질 때 까지 대기하기 위한)을 제거해 보았다. 그랬더니 센서 B로부터 응답이 돌아왔다. 정상적으로 동작한 것이다.

나로써는 프로젝트의 규모가 커졌다고는 하나 고작 16byte데이터를 보내는데 함수호출방식을 사용한다고 DSP 내부적으로 어떤 문제가 발생할 수 있는지 모르겠다.


센서 B와 통신이 정상화 되었더니 이번에는 센서 A로부터 응답이 없다.

센서 A는 B와는 전혀 다른 센서였는데, 명령 커맨드를 보내주면 이후에 요청한 정보를 계속 전송해 준다. 따라서 명령 커맨드가 제대로 전송되지 않았다고 보았다.

실제로 제거했던 while문을 다시 넣었더니 동작하는 것이다. 이 점에 있어서는 DSP의 문제라기 보다는 센서 A가 데이터를 수신할 때 어느정도의 텀이 필요한것이 아닌가 생각되었다.

결국 센서 A와 센서 B에 대하여 다른 전송 함수를 사용할 수 밖에 없었다.


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

센서 B와 관련해서는 함수호출방식을 아예 배제하기 위해서 Write 함수의 빨간 코드 부분을 아래와 같이 바꾸었다.


for(i=0; i<EOI; i++){

TXData = data[i];

pChannel->SCITXBUF.all=(TXData&0x00ff);

pChannel->SCITXBUF.all=((TXData&0xff00)>>8);

}


만약 C++로 개발중이었다면 가볍게 인라인 함수로 함수화 했을텐데 아쉬운 부분이다.

Posted by 십자성군
TMS320/F283352017. 2. 9. 11:12


#define SYSCLK 150E6 /* 150MHz */

#define TBCLK 2343750 /* 60MHz */

#define     PWMCARRIER 20000 /* 20KHz */ (? : 목표 pwm 주파수?)



void InitEPwm1Module(void)

{

/* Setup TBCLK */

//PWM Counter Set

EPwm1Regs.TBPRD = (TBCLK/PWMCARRIER)-1;                         /* Set Timer Period */

EPwm1Regs.TBCTR = 0;                 /* Clear Counter */


/* Set Compare values */

EPwm1Regs.CMPA.half.CMPA = ((EPwm1Regs.TBPRD+1)>>1); /* Set Compare A value to 50% */

EPwm1Regs.CMPB = ((EPwm1Regs.TBPRD+1)>>1); /* Set Compare B value to 50% */


/* Setup counter mode */

EPwm1Regs.TBCTL.bit.CTRMODE = TB_COUNT_UP; /* Count Up (Asymmetric) */

EPwm1Regs.TBPHS.half.TBPHS = 0; /* Phase is 0 */

EPwm1Regs.TBCTL.bit.PHSEN = TB_DISABLE; /* Disable phase loading */

EPwm1Regs.TBCTL.bit.PRDLD = TB_SHADOW; /* Period Register is loaded from its shadow when                                                                                 CNTR=Zero */

EPwm1Regs.TBCTL.bit.HSPCLKDIV = 0x0;                 /* Clock ratio to SYSCLKOUT */

EPwm1Regs.TBCTL.bit.CLKDIV = 0x6;                 /* TBCLK = SYSCLK / (HSPCLKDIV * CLKDIV) */ //important


/* Setup shadowing */

EPwm1Regs.CMPCTL.bit.SHDWAMODE = CC_SHADOW; /* Enable Shadowing */

EPwm1Regs.CMPCTL.bit.LOADAMODE = CC_CTR_ZERO; /* Load on CNTR=Zero */


EPwm1Regs.CMPCTL.bit.SHDWBMODE = CC_SHADOW;

EPwm1Regs.CMPCTL.bit.LOADBMODE = CC_CTR_ZERO;


/* Set actions */

EPwm1Regs.AQCTLA.bit.ZRO = AQ_SET;                 /* Set EPWM1A on CNTR=Zero */

EPwm1Regs.AQCTLA.bit.CAU = AQ_CLEAR;                 /* Clear EPWM1A on event A, up count */


EPwm1Regs.AQCTLB.bit.ZRO = AQ_SET;

EPwm1Regs.AQCTLB.bit.CBU = AQ_CLEAR;

}


이전 자료와 함께 설명한다.(http://yeahhappyday.tistory.com/search/epwm)


DSP 28335의 SYSCLK는 150Mhz 이다.

TBCLK는 Time Base clock을 의미하며 pwm의 clock으로써 사용한다.

이는 SYSCLK에서 분배하여 그 값을 정하며 수식적으로는 위에 표시해 놓았듯이 TBCLK = SYSCLK / (HSPCLKDIV * CLKDIV) 이다.

관련 그림은 다음과 같다.

위 소스에서는 CLKDIV를 0x6, HSPCLKDIV를 0으로 해놓았기 때문에 TBCLK는 150Mhz/64 로 2343750hz 가 된다.




위 그림을 보면 어떻게 돌아가는지 일목요연하다.

코드에 설정해 놓은것을 분석해 놓으면

150Mhz인 SYSCLK에서 1/64를 한 값인 2343750hz를 TBCLK로 설정하였으며

이에 역수를 취한 2343750^(-1) 값은 4.26e-7인데 이는 PWM생성을 위한 카운트 주기가 된다.

TBPRD값을 2343750/20000-1을 한 값은 116인데 이는 위에 설정한 카운트 주기에 대하여 117회 카운트를 한 것을 PWM의 1주기로 잡는다는 것이다.

따라서 (4.26e-7)*117 = 0.00004992 로 약 0.05ms(20kHz) 를 pwm의 한 주기로 설정한다는 것이다.


TBCLK : 2343750hz : 4.26e-7 (sec)

TBPRD : 117 count

PWM 주기 : 4.26e-7 * 117 = 0.00004992 (sec)

'TMS320 > F28335' 카테고리의 다른 글

DSP 28335, 28377 flash 작업을 위한 기본자료  (0) 2017.02.22
DSP28335 Flash programming  (0) 2017.02.19
DSP 프로젝트 생성(28377, 28335 공통)  (0) 2016.11.21
Baudrate 설정  (0) 2016.10.09
InitPeripheralClocks  (0) 2016.03.09
Posted by 십자성군
기타/문제해결기2017. 2. 3. 12:22

참고 : http://www.ehowstuff.com/how-to-fix-you-could-try-using-skip-broken-to-work-around-the-problem-error/


내용

-설치 유틸리티 list에 대한 업데이트가 필요한게 아닐까 하다.

-list를 업데이트하고 이전 캐시를 지우라는 내용이려나?

Posted by 십자성군
기타/문제해결기2017. 2. 2. 21:51

참고 : http://stackoverflow.com/questions/23067886/vfy-unable-to-resolve-lots-of-stuff


사용되지 않는 가상함수가 선언되어 있는듯 하다. 이를 사용하지 않는 한 문제는 없다고 한다.

Posted by 십자성군
기타/문제해결기2017. 2. 2. 20:20

참고 : http://raspberrypi.stackexchange.com/questions/14101/connect-network-is-unreachable-on-a-working-connected-wlan0-interface


가설정 문제 등에서 문제가 없으나 WiFi 연결하고 인터넷이 사용 불가능 할 때.

Gateway설정이 되어있지 않은 것이다.



Posted by 십자성군