Thursday, November 1, 2007

volatile, __no_init

DECLARING OBJECTS VOLATILE
There are three main reasons for declaring an object volatile:
● Shared access; the object is shared between several tasks in a multitasking
environment
● Trigger access; as for a memory-mapped SFR where the fact that an access occurs
has an effect
● Modified access; where the contents of the object can change in ways not known to
the compiler.


Variables that are accessed from multiple threads, for example from main or an
interrupt, must be properly marked and have adequate protection, the only exception to
this is a variable that is always read-only.

To mark a variable properly, use the volatile keyword. This informs the compiler,
among other things, that the variable can be changed from other threads. The compiler
will then avoid optimizing on the variable (for example, keeping track of the variable in
registers), will not delay writes to it, and be careful accessing the variable only the
number of times given in the source code.

The object attribute must be placed in front of the type. For example, to place myarray
in memory that is not initialized at startup:
__no_init int myarray[10];

__no_init
Syntax Follows the generic syntax rules for object attributes, see Object attributes, page 169.
Description Use the __no_init keyword to place a data object in non-volatile memory. This means
that the initialization of the variable, for example at system startup, is suppressed.
Example __no_init int myarray[10];


In the following examples, there are two const declared objects, where the first is
initialized to zero, and the second is initialized to a specific value. Both objects are
placed in ROM. This is useful for configuration parameters, which are accessible from
an external interface. Note that in the second case, the compiler is not obliged to actually
read from the variable, because the value is known. To force the compiler to read the
value, declare it volatile:
#pragma location=0x1004
volatile const int beta; /* OK */
volatile const int gamma @ 0x1008 = 3; /* OK */

In the following example, the value is not initialized by the compiler; the value must be
set by other means. The typical use is for configurations where the values are loaded to
ROM separately, or for special function registers that are read-only. To force the
compiler to read the value, declare it volatile:
volatile __no_init const char c @ 0x1004;

The following examples show incorrect usage:
int delta @ 0x100C; /* Error, neither */
/* "__no_init" nor "const".*/
const int epsilon @ 0x1011; /* Error, misaligned.

Sunday, October 14, 2007

UART RX interrupt

因接收端產生的中斷, ISR會將UART FIFO所Buffer的資料移到Queue.
如果Queue已滿了(無法將FIFO所buffer的資料量降至INT trigger level)然後離開ISR。
若再接收到資料還會再產生中斷嘛?
答案是會的,即使FIFO & Queue都滿了,在ISR中正確的將INT Flag清除後,每收到一個位元組依舊會產生中斷。

Wednesday, October 10, 2007

UART Failure

bool
UART_Putc( c, delay)
{
if( QU_IsEmpty(&TxQu_Uart1) )
{
if( !(UART1->FR & UART_FR_TXFF_MASK) ) {
UART1->DR = c;
return true;
}
}

if( !QU_IsFull(&TxQu_Uart1) ) ---> 若這時中斷產生,跳躍至IRQ handler,IRQ handler將
{ Queue的資料填入UART FIFO, 所填入的資料量依舊無
taskENTER_CRITICAL(); 法使INT flag清除, 所以只好強制清除INT flag.
QU_Append(&TxQu_Uart1, c); 問題出現,把資料Append至Queue後,這時再也不會產
taskEXIT_CRITICAL(); 生中斷。 再次再進入UART_Putc便不會把資料Put至
return true; FIFO, 而是放到Queue。----> UART function failed.
}

} /* UART_Putc */


P.S.
清除UART INT flag的方式,
I. 填入UART FIFO的資料大於INT trigger level.
Ex: trigger level == 8,則當中斷發生的時候,FIFO所buffer的資料已小於8,這時必須將FIFO的資料填入超過8,方可清除INT flag。
II. UART1->ICR = UART_ICR_TXIC_MASK; /* Clear interruption flag. */

Saturday, October 6, 2007

Hardware breakpoint / Software breakpoint

ARM7 & ARM9分有2個Hardware breakpoint (called "watchpoint units" in ARM's documentation), Hardware breakpoint不需要修改code, 但是Software breakpoint則不同, debugger會更改breakpoint所在的指令, 填一入特定的值. 如此便沒有breakpoint數量的限制, 但唯一的限制就是Code是必須run在RAM才行。

但是如果沒有External RAM的話, 還有其它辦法可以解決Breakpoint不足的問題.
請參考(C:\Program Files\SEGGER\JLinkARM_V374i\Doc\Manuals\JLinkRDI.pdf).

J-Link Usage

J-Link Introduction
IAR的J-Link就是Segger作的.

J-Link Utility Download
JLinkARM.dll
要檢查目前IAR所使用的版本是不是較新的.

J-Mem.exe
CPU run起來後, 可透過它更改memory的資料.

JLinkRDI
由於ARM core本身只有兩個Hardware breakpoint, 如果需要更多的Breakpoint就可以使用RDI, IAR project->option->RDI.
PS. RDI: Remote Debug Interface
Q: Manual(C:\Program Files\SEGGER\JLinkARM_V374i\Doc\Manuals\JLinkRDI.pdf)上有講到, Download into Flash without the need for a Flash loader. What's that mean?

JLinkTCPIPServer.exe
跟ARM Multi-ICE一樣可透過TCP/IP使用J-Link/J-Trace

Reference:
JLinkARM.pdf, 該文件中有介紹在一台PC上同時使用兩個以上的ICE (J-Trace/J-Link). 依照該文件的設定無法使用。使用jlinkarm.dll版本為:3.56.6.0便可行。

Sunday, September 16, 2007

Ymodem TX

Ymodem reference I
Ymodem reference II
ftp://ftp.simtel.net/pub/simtelnet/msdos/turbopas/htmlswag10.zip
COMM/0084.PAS


Reference I--------------------------------------------
Sender Receiver
C
C
SOH 00 FF Y/Zmodem Header[128] crchi crclo
ACK
C

STX 01 FE data[1024] crchi crclo
ACK
STX 02 FD data[1024] crchi crclo
NAK
STX 02 FD data[1024] crchi crclo
ACK
STX 03 FC data[1024] crchi crclo
ACK
STX 04 FB data[1024] crchi crclo
ACK
EOT
NAK
EOT
ACK
C
SOH 00 FF NUL[128]
---------------------------------------------------------

Reference II--------------------------------------------
Sender Receiver
C
C
SOH 00 FF Y/Zmodem Header[128] crchi crclo
ACK
C

STX 01 FE data[1024] crchi crclo
ACK
STX 02 FD data[1024] crchi crclo
NAK
STX 02 FD data[1024] crchi crclo
ACK
STX 03 FC data[1024] crchi crclo
ACK
STX 04 FB data[1024] crchi crclo
ACK
EOT
ACK
C
SOH 00 FF NUL[128]
---------------------------------------------------------
Reference I
所定義的Ymodem和Reference II所定義的有點不相同.
若使用Windows, hyper terminal接收檔案,傳送端必須使用Reference II.

Thursday, September 13, 2007

ARM_init.s

修改FMI module, 修改
開機區、非開機區的Flash size, 起啟位置, 終止位置
系統若有Bootloader則不需執行這些initial code.


; --- Remap Flash Bank 0 at address 0x0 and Bank 1 at address 0x80000,
; when the bank 0 is the boot bank, then enable the Bank 1.

LDR R6, =0x54000000 ; BOOT BANK Size = 512KB
LDR R7, =0x4 ; (2^4) * 32 = 512KB
STR R7, [R6]

LDR R6, =0x54000004 ; NON BOOT BANK Size = 32KB
LDR R7, =0x2 ; (2^2) * 8 = 32KB
STR R7, [R6]

LDR R6, =0x5400000C ; BOOT BANK Address = 0x0
LDR R7, =0x0
STR R7, [R6]

LDR R6, =0x54000010 ; NON BOOT BANK Address = 0x80000
LDR R7, =0x20000 ; need to put 0x20000 because FMI bus on A[25:2] of CPU bus
STR R7, [R6]

LDR R6, =0x54000018 ; Enable CS on both banks
LDR R7, =0x18
STR R7, [R6]

Tuesday, September 11, 2007

IAR library building

XAR Library builder: Combine a set of UBROF object files into a library file.
XLIB librarian: can do a number of things in addition to building libraries: modify the size and contents of existing libraries, list information about individual library modules, and more.
--> Both tools use the UBROF standard object format(Universal Binary Relocatable Object Format).

XLIB功能多於XAR, 若只是單純的把數個Object file(UBROF)作成一Library, XAR便已足夠了。

IAR File Type

Reference: EWARM_UserGuide.pdf
.d79: Target application with debug information, output from: XLINK
.i: Preprocessed source, output from: compiler
.i79: ARM chip settings, input to IAR embedded workbench
.lst: List output, output fromL XLINK
.r79: Object module
.xcl: Extended command line
.mac: C-SPY macro definition, input to: C-SPY

.ewd: Project setting for C-SPY, output from:IAR Embedded Workbench
.ewp: IAR Embedded workbench project
.eww: Workspace file

Sunday, July 29, 2007

eCos

eCos is an open source, royalty-free, real-time operating system intended for embedded applications.

Introduction to eCos
Reference book: Embedded Software Development with eCos

Wednesday, May 23, 2007

Securing & Unsecuring Flash, E64 & E256

Secure Flash:

加密後的Flash是無法經外部BDM or Cyclone Pro讀取Flash內容。
加密的方法是在Flash 0xFF0F的位址寫入0x80 or 0x81 or 0x83,重新開機後MCU會把0xFF0F的值載入FSEC暫存器。FSEC[1:0]所代表即是目前Flash的加密狀態。
After reset, @FF0F
--> FSEC

Unsecure Flash:

FSEC是唯讀的,不能經由改寫FSEC[1:0]改變Flash的加密狀態。
解密的方法有二:
一、使用Backdoor key, 可暫時的將Flash解密。這個方法通常是由外部提供Keys, 如經由RS232輸入。
二、抹除0xFF0F所在的Sector (0xff00 == 0x3FBF00). 然後將0xFF0F寫入0x82,重新開後 @FF0F à FSEC,便可將Flash解密。抹除的工作都必需是由MCUFirmware



想不到是AN2880SW有問題,之前可能都沒人試吧!
KEYACC @ FCNFG[5] 被設成1之後是無法讀取Flash資料的。
但是在AN2880SW的程式中犯了這樣的錯誤。

Monday, May 14, 2007

HCS12, Flash Security

欲燒錄位於 0xFF00 ~ 0xFFFF Flash 前
(P.S. 0xFF00 == 0x3FBF00)
先抹除,
   add = 0x003FBFF0;
   Flash_SectorErase(add);
再開始執行燒錄的工作。

問題:抹除後就無法對 Flash 作操作了。
推測可能是 Security byte 的問題,抹除後,在位址 0x3FBFF0F 寫入 0xFE
就可以了。

Friday, May 11, 2007

HCS12 Bootloader, Interrupt Table Arrangement

After reset, The bootloader's startup routine is called,
startup routine 將 RAM 的位址 remap 至 0xF000 ~ 0xFFFF (4KB).
原先在該範圍的 Flash 便無法使用。
所參考的中斷向量便是存放 RAM 中, 而不是在 Flash.

Bootloader 可正常的使用中斷, 但需注意的是在程式中的宣告,
不可使用 constant 來宣告中斷向量表。
const INT16U INTsTable[] @ 0xFF00 = {.....}; (X)
INT16U INTsTable[] @ 0xFF00 = {.......};         (O)

如此一來 startup routine 在執行初始化全域變數時才會將 Interrupt vectors 填入.
不然中斷向量會被當成常數存在放 Flash 裡。


Bootloader 更新 Application Interrupt table 時, 因為中斷向量表位在: 0xFF00 ~ 0xFFFF
, 和目前的 RAM 位址重疊。要如何才能將中斷向量燒錄至 Flash 位於 0xFF00 ~ 0xFFFF 的位址?

Flash: 0xC000 ~ 0xFFFF == 0x3F8000 ~ 0x3FBFFF (Banked memory)

燒錄時可將位址作上述的轉換應該可以解上述的問題。(不過我還沒試過)
Reference

HCS12 Image File Arrangement

Image file = Application image + Bootloader image
The entry point of application has to be place in firm address.
先前假設 entry point 都會是固定的位址,風險有點高!
假設新編譯的執行檔其entry point不是在假設的位址,那便都開不了機了。

〝固定的位址〞, Bootloader 也必需知道這個位址。Bootloader 跳至 application
執行前必需到這個位址擷取 entry point.

Thursday, May 10, 2007

Unused Flash

如系統遭受EMI影響,系統行為 erratically,也就是使 PC(program counter )已不正確。This is called code-runaway.
未使用的Flash memory 其值為0xFF. 若程式執行時會將其解讀為 ' LDS $FFFF '

A simple solution is to fill unused Flash with $3F, the op-code for the SWI instruction. As this is a single byte instruction, it will always be executed correctly. The microcontroller will fetch the Software Interrupt Vector and execute the code at the address.

If the Software Interrupt is required by the application, an alternative solution is to use 'Implemented Instrutction' interrupt. As all page 1 op-codes are valid, it is necessary to choose a page 2 op-code. Filling unused Flash with $18A7 will cause an 'Unimplemented Instruction' interrupt if the CPU attempts to execute this op-code. $18 is pre-byte to select page 2, and $A7 is unimplemented on page 2. If the $A7 is read first, this will be interpreted as a NOP instruction and the next $18A7 will be read.

Unimplemented Opcode Trap

The CPU12 has opcodes in all 256 positions in the page 1 opcode map,
but only 54 of the 256 positions on page 2 of the opcode map are used.
If the CPU attempts to execute one of the 202 unused opcodes on
page 2, an unimplemented opcode trap occurs. The 202 unimplemented
opcodes are essentially interrupts that share a common interrupt vector,
$FFF8:$FFF9.
The CPU12 uses the next address after an unimplemented page 2
opcode as a return address. This differs from the M68HC11 illegal
opcode interrupt, which uses the address of an illegal opcode as the
return address. In the CPU12, the stacked return address can be used
to calculate the address of the unimplemented opcode for
software-controlled traps.

Flash module can’t run smoothly.

Description:

每從Flash_RamFunc() return便會當機!

Reason:

Trace stack point, 差別在於函式結尾組合語言" RTC", " RTS".
RTC:
不會考慮PAGE number, 適用 Memory mode: Small
RTS:
考慮PAGE number, 適用 Memory mode: Banked

Saturday, March 31, 2007

RTC, DS1340

Interface: I2C
Device address: 0b1101000x
SPEC裡說明讀取的部份不是很清楚,
Start == Read Command == Data == ... == Stop
Command: Device address + Read bit.
照著上列順序並沒辦法讀到資料。

在讀取資料前必須先以Write command將欲讀取的位址寫入才可。
Start == Write Command == Data Address

完整的讀取順序:
Start == Write Command == Data Address == Re-Start == Read Command == Data == ... == Stop

Code Reference

Tuesday, March 20, 2007

Ubuntu

Ubuntu Home Page | Ubuntu: "What is Ubuntu?

Ubuntu is a community developed, linux-based operating system that is perfect for laptops, desktops and servers. It contains all the applications you need - a web browser, presentation, document and spreadsheet software, instant messaging and much more."

Friday, March 16, 2007

Cortex-M3

Cortex-M3, cost down的ARM7TDMI
但是在Cortex-M3 和 ART7TDMI的比較發現到雖然Cost Down, 可是功能卻比ARM7TDMI優。不論是code size, cost, die footprint, power consumption, performance, 而且還多了一個Nested Vectored Interrupt Controller.

ARM Cortex-A Series: Applications processors for complex OS and user applications
ARM Cortex-R Series: Embedded processors for real-time systems
ARM Cortex-M Series: Deeply embedded processors optimized for microcontroller and low-cost applications

Thursday, March 15, 2007

ARM Purchases Keil Software

ARM把Keil買下來了哦!
http://www.microcontroller.com/news/arm_keil.asp

As the MCU applications shift from 8/16-bit to 32-bit solutions, the combination of the ARM Cortex processor, which was specifically designed for microcontroller applications, our RealView high-performance compiler, and Keil's complementary MCU tools for ARM, will enable new generations of ARM MCU solutions.
----------------------------------------------------------------------------
原來ARM Cortex-M3 processor 是專為MCU應用所設計的!

Wednesday, March 14, 2007

Decision

看來老闆還是蠻喜歡用ST的, 可能是他們的價錢好談。
但不知道會不會像Microchip一樣program時還注意一些奇奇怪怪的問題。