Saturday, December 29, 2007
Thursday, November 1, 2007
volatile, __no_init
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
如果Queue已滿了(無法將FIFO所buffer的資料量降至INT trigger level)然後離開ISR。
若再接收到資料還會再產生中斷嘛?
答案是會的,即使FIFO & Queue都滿了,在ISR中正確的將INT Flag清除後,每收到一個位元組依舊會產生中斷。
Wednesday, October 10, 2007
UART Failure
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
但是如果沒有External RAM的話, 還有其它辦法可以解決Breakpoint不足的問題.
請參考(C:\Program Files\SEGGER\JLinkARM_V374i\Doc\Manuals\JLinkRDI.pdf).
J-Link Usage
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 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
開機區、非開機區的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
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
.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
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解密。抹除的工作都必需是由MCU的Firmware。
想不到是AN2880SW有問題,之前可能都沒人試吧!
KEYACC @ FCNFG[5] 被設成1之後是無法讀取Flash資料的。
但是在AN2880SW的程式中犯了這樣的錯誤。
Monday, May 14, 2007
HCS12, Flash Security
(P.S. 0xFF00 == 0x3FBF00)
先抹除,
add = 0x003FBFF0;
Flash_SectorErase(add);
再開始執行燒錄的工作。
問題:抹除後就無法對 Flash 作操作了。
推測可能是 Security byte 的問題,抹除後,在位址 0x3FBFF0F 寫入 0xFE
就可以了。
Friday, May 11, 2007
HCS12 Bootloader, Interrupt Table Arrangement
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
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
未使用的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
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.
每從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
Tuesday, March 20, 2007
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 和 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
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應用所設計的!