linker optimization

This site uses cookies. By continuing to browse this site, you are agreeing to our Cookie Policy.

  • linker optimization

    Hi !
    I'm starting the finalization of my new project based on a LPC4350 (8MB SPIFI + 64MB SDRAM).
    I'm using the EmWin library provided by NXP (emWin_520_Keil460_M4_LE.lib).
    The application displays "animations", which are no more than a succession of .dta files stored in SPIFI.
    The application windows are based on the Window Manager.

    I would like to optimize the speed of the animation.
    One way is to excecute some part of emWin from the internal RAM (5x faster than SPIFI).
    Because I don't have the source code, and still not my JTAG with performance analyser, could you please indicate me which files are the most "CPU consumming" for displaying DTA images ?

    I have already done this optimization for my OS (FreeRTOS) and my Ethernet stack (LwIP).

    Thank you very much for your support.

    Laurent


    Hereafter, an exemple of a window creation with animation inside.
    ani_start() launches a timer. On timer end, the new DTA file is displayed.

    C Source Code

    1. /*********************************************************************
    2. * *
    3. * SEGGER Microcontroller GmbH & Co. KG *
    4. * Solutions for real time microcontroller applications *
    5. * *
    6. **********************************************************************
    7. * *
    8. * C-file generated by: *
    9. * *
    10. * GUI_Builder for emWin version 5.16 *
    11. * Compiled Jun 4 2012, 15:48:59 *
    12. * (c) 2011 Segger Microcontroller GmbH & Co. KG *
    13. * *
    14. **********************************************************************
    15. * *
    16. * Internet: www.segger.com Support: support@segger.com *
    17. * *
    18. **********************************************************************
    19. */
    20. // USER START (Optionally insert additional includes)
    21. // USER END
    22. #include "DIALOG.h"
    23. #include "MMI_eraseDLG.h"
    24. #include "romfs_spifi.h"
    25. #include "GUI_main.h"
    26. #include "GUI_common.h"
    27. #include "MMI_configuration.h"
    28. #include "status_collector.h"
    29. #include "fpga_task.h"
    30. #include "door_task.h"
    31. #include "database.h"
    32. #include "product_configuration.h"
    33. #include "lpc_arch.h"
    34. #include "led_output.h"
    35. /*********************************************************************
    36. *
    37. * Defines
    38. *
    39. **********************************************************************
    40. */
    41. #define ID_WINDOW_0 (GUI_ID_USER + 0x00)
    42. #define ID_IMAGE_0 (GUI_ID_USER + 0x01)
    43. //#define ID_IMAGE_1 (GUI_ID_USER + 0x02)
    44. #define ID_IMAGE_2 (GUI_ID_USER + 0x03)
    45. #define ID_IMAGE_3 (GUI_ID_USER + 0x04)
    46. #define ID_IMAGE_4 (GUI_ID_USER + 0x05)
    47. #define ID_TEXT_0 (GUI_ID_USER + 0x06)
    48. // USER START (Optionally insert additional defines)
    49. #define ERASE_PRESS_NONE 0
    50. #define ERASE_PRESS_PARAM 1
    51. #define ERASE_PRESS_HOME 2
    52. #define ERASE_STATE_WAIT 1
    53. #define ERASE_STATE_RETURN 2
    54. #define ERASE_STATE_ERASE 3
    55. // USER END
    56. extern uint32_t door_task_state;
    57. /*********************************************************************
    58. *
    59. * Static data
    60. *
    61. **********************************************************************
    62. */
    63. // USER START (Optionally insert additional static data)
    64. extern struct gui_win_struct gui_win;
    65. extern char mmi_dyn_txt[100];
    66. extern uint32_t key_state;
    67. extern GUI_PID_STATE my_ts_state;
    68. uint16_t erase_state;
    69. uint16_t erase_state_last;
    70. uint32_t erase_force_motor_cpt;
    71. // USER END
    72. /*********************************************************************
    73. *
    74. * _aDialogCreate
    75. */
    76. static const GUI_WIDGET_CREATE_INFO _aDialogCreate[] = {
    77. { WINDOW_CreateIndirect, "MMI_connected", ID_WINDOW_0, 0, 0, 320, 240, 0, 0, 0 },
    78. { IMAGE_CreateIndirect, "background", ID_IMAGE_0, 0, 0, 320, 240, 0, 0, 0 },
    79. // { IMAGE_CreateIndirect, "anim_static", ID_IMAGE_1, 20, 50, 120, 170, 0, 0, 0 },
    80. { IMAGE_CreateIndirect, "anim_mov", ID_IMAGE_2, ANI_POS_X, ANI_POS_Y, ANI_X, ANI_Y, 0, 0, 0 },
    81. { IMAGE_CreateIndirect, "home", ID_IMAGE_3, HOX, HOY, ISX, ISY, 0, 0, 0 },
    82. { IMAGE_CreateIndirect, "param", ID_IMAGE_4, POX, POY, ISX, ISY, 0, 0, 0 },
    83. { TEXT_CreateIndirect, "progress", ID_TEXT_0, 170, 80, 120, 50, 0, 100, 0 },
    84. // USER START (Optionally insert additional widgets)
    85. // USER END
    86. };
    87. /*********************************************************************
    88. *
    89. * Static code
    90. *
    91. **********************************************************************
    92. */
    93. // USER START (Optionally insert additional static code)
    94. // USER END
    95. /*********************************************************************
    96. *
    97. * _cbDialog
    98. */
    99. static void _cbDialog(WM_MESSAGE * pMsg) {
    100. WM_HWIN hItem;
    101. int Id, NCode;
    102. // USER START (Optionally insert additional variables)
    103. erase_force_motor_cpt = 0;
    104. // USER END
    105. switch (pMsg->MsgId) {
    106. case WM_INIT_DIALOG:
    107. mmi_window_timeout_reset();
    108. reset_image_button();
    109. key_state = KEY_RELEASED;
    110. erase_state = ERASE_STATE_WAIT;
    111. //
    112. // Initialization of 'background'
    113. //
    114. hItem = WM_GetDialogItem(pMsg->hWin, ID_IMAGE_0);
    115. display_picture_from_rom(hItem, IMG_ERAS_BACKGROUND);
    116. //
    117. // Initialization of 'anim_mov'
    118. //
    119. hItem = WM_GetDialogItem(pMsg->hWin, ID_IMAGE_2);
    120. display_picture_from_rom(hItem, IMG_ERAS_ANI_INSERT);
    121. ani_start();
    122. //
    123. // Initialization of 'home'
    124. //
    125. hItem = WM_GetDialogItem(pMsg->hWin, ID_IMAGE_3);
    126. display_picture_from_rom(hItem, IMG_ERAS_HOME);
    127. //add_image_action(ERASE_PRESS_HOME, ID_IMAGE_3, nb_element, _aDialogCreate);
    128. //
    129. // Initialization of 'param'
    130. //
    131. hItem = WM_GetDialogItem(pMsg->hWin, ID_IMAGE_4);
    132. display_picture_from_rom(hItem, IMG_ERAS_PARAM);
    133. //add_image_action(ERASE_PRESS_PARAM, ID_IMAGE_4, nb_element, _aDialogCreate);
    134. //
    135. // Initialization of 'progress'
    136. //
    137. hItem = WM_GetDialogItem(pMsg->hWin, ID_TEXT_0);
    138. TEXT_SetTextAlign(hItem, GUI_TA_LEFT | GUI_TA_VCENTER);
    139. TEXT_SetFont(hItem, FONT_ERAS_PROGRESS);
    140. TEXT_SetTextColor(hItem, COLOR_ERAS_PROGRESS);
    141. TEXT_SetText(hItem, "");
    142. // USER START (Optionally insert additional code for further widget initialization)
    143. // USER END
    144. break;
    145. case WM_NOTIFY_PARENT:
    146. //int Id, NCode;
    147. if ((key_state != KEY_BLOCKED) && (erase_state == ERASE_STATE_WAIT)) {
    148. Id = WM_GetId(pMsg->hWinSrc);
    149. NCode = pMsg->Data.v;
    150. switch(Id) {
    151. case ID_IMAGE_3: // Notifications sent by 'home'
    152. switch(NCode) {
    153. case WM_NOTIFICATION_RELEASED:
    154. mmi_back_home();
    155. door_end_force_motor();
    156. key_state = KEY_BLOCKED;
    157. break;
    158. default:
    159. break;
    160. }
    161. break;
    162. case ID_IMAGE_4: // Notifications sent by 'param'
    163. switch(NCode) {
    164. case WM_NOTIFICATION_RELEASED:
    165. mmi_exit_to(WIN_MENU_CREATE);
    166. // gui_win.exit_request = 1;
    167. // gui_win.next_window = WIN_MENU_CREATE;
    168. key_state = KEY_BLOCKED;
    169. break;
    170. default:
    171. break;
    172. }
    173. break;
    174. case ID_IMAGE_2: // Notifications sent by 'erase'
    175. switch(NCode) {
    176. case WM_NOTIFICATION_CLICKED:
    177. ani_stop();
    178. door_force_motor();
    179. mmi_window_timeout_reset();
    180. break;
    181. case WM_NOTIFICATION_RELEASED:
    182. while (DOOR_SCAN_sWAIT_END_MOTOR != door_task_state) {
    183. msDelay(100);
    184. erase_force_motor_cpt ++;
    185. if (erase_force_motor_cpt > 20) {
    186. door_end_force_motor();
    187. ani_start();
    188. break;
    189. }
    190. mmi_window_timeout_reset();
    191. }
    192. door_end_force_motor();
    193. ani_start();
    194. break;
    195. case WM_NOTIFICATION_MOVED_OUT:
    196. break;
    197. default:
    198. break;
    199. }
    200. break;
    201. default:
    202. break;
    203. }
    204. }
    205. break;
    206. // USER START (Optionally insert additional message handling)
    207. // USER END
    208. default:
    209. WM_DefaultProc(pMsg);
    210. break;
    211. }
    212. }
    213. /*********************************************************************
    214. *
    215. * Public code
    216. *
    217. **********************************************************************
    218. */
    219. /*********************************************************************
    220. *
    221. * CreateMMI_connected
    222. */
    223. //WM_HWIN CreateMMI_connected(void);
    224. WM_HWIN CreateMMI_erase(void) {
    225. WM_HWIN hWin;
    226. hWin = GUI_CreateDialogBox(_aDialogCreate, GUI_COUNTOF(_aDialogCreate), &_cbDialog, WM_HBKWIN, 0, 0);
    227. return hWin;
    228. }
    229. // USER START (Optionally insert additional public code)
    230. // USER END
    231. /*************************** End of file ****************************/
    Display All
  • Hello Laurent,

    Time consumption regarding dta files depends on the used function. In case you are going to use one of the functions which are designed to fetch the data directly from external memory (...Ex()-function), the time consuming part will be the fetching (GetData()-function). For detailed information on how to display dta images, please refer to the chapter 2-D Graphic Library in the emWin user manual.

    Best regards,
    Adrian
  • I Adrian,

    thank you very much for your reply.
    SPIFI memory is mapped as internal memory by the LPC4350.

    The function I call to display my DTA file is IMAGE_SetDTA(). (see code below)
    You are right, fetching data can be time consuming. I'm working on this side also (cache in external RAM).

    What I need to know is if there is some 'CPU consuming' functions than I can locate in internal RAM to accelerate the process of DTA file on WM window with alpha channel.

    Thank you for your support,

    Laurent

    Brainfuck Source Code

    1. /*---------------------------------------------------------------------------*
    2. * Routine: display_picture_from_rom
    3. *---------------------------------------------------------------------------*
    4. * Description:
    5. * generic function for picture display from SPIFI
    6. *
    7. * Inputs:
    8. * WM_HWIN htem
    9. * char * pic_name
    10. * Outputs:
    11. * void
    12. *---------------------------------------------------------------------------*/
    13. void display_picture_from_rom(WM_HWIN htem, char * pic_name)
    14. {
    15. const void * pData;
    16. U32 FileSize;
    17. char* index;
    18. uint8_t c;
    19. if (strncmp (pic_name, IMG_NO, strlen(IMG_NO)) == 0) {
    20. IMAGE_SetBitmap(htem, &bmimage_no);
    21. return;
    22. }
    23. pData = gui_romfs_file_open(pic_name, &FileSize);
    24. if (FileSize == 0) {// file not found
    25. IMAGE_SetBitmap(htem, &bmno_image);
    26. } else {
    27. // file found, determine the type !
    28. index = pic_name;
    29. c = 0;
    30. while (index[code=c] != '\0') {
    31. if (index[code=c] == '.') { // found the extension !
    32. index += (c + 1);
    33. if (strncmp (index, "jpg", 3) == 0) {
    34. IMAGE_SetJPEG(htem, pData, FileSize);
    35. } else if (strncmp (index, "jpeg", 4) == 0) {
    36. IMAGE_SetJPEG(htem, pData, FileSize);
    37. } else if (strncmp (index, "bmp", 3) == 0) {
    38. IMAGE_SetBMP(htem, pData, FileSize);
    39. } else if (strncmp (index, "gif", 3) == 0) {
    40. IMAGE_SetGIF(htem, pData, FileSize);
    41. } else if (strncmp (index, "png", 3) == 0) {
    42. IMAGE_SetPNG(htem, pData, FileSize);
    43. } else if (strncmp (index, "dta", 3) == 0) {
    44. IMAGE_SetDTA(htem, pData, FileSize);
    45. } else if (strncmp (index, "ani", 3) == 0) {
    46. decode_ani_file(htem, pData, FileSize);
    47. } else { // image extension not supported !
    48. IMAGE_SetBitmap(htem, &bmno_image);
    49. }
    50. return;
    51. }
    52. if (c > FILE_NAME_MAX_SIZE) { // error !
    53. IMAGE_SetBitmap(htem, &bmno_image);
    54. return;
    55. }
    56. c ++;
    57. }
    58. }
    59. }
    Display All