static void privilege_task(uint_32 initial_data) { _mqx_uint msg[MSG_SIZE]; _lwmem_pool_id mem_pool_id; LWMEM_POOL_STRUCT mem_pool; pointer mem_pool_start; LWMEM_POOL_STRUCT_PTR usr_pool_ptr; pointer usr_pool_start; /* memory pool: Read-Only for User tasks */ mem_pool_start = _mem_alloc(1024); mem_pool_id = _lwmem_create_pool(&mem_pool, mem_pool_start, 1024); _mem_set_pool_access(mem_pool_id, POOL_USER_RO_ACCESS); /* message queue to communicate between this task and User tasks */ que = (uint_32*)_mem_alloc_from(mem_pool_id, sizeof(LWMSGQ_STRUCT) + NUM_MESSAGES * MSG_SIZE * sizeof(_mqx_uint)); _usr_lwmsgq_init((pointer)que, NUM_MESSAGES, MSG_SIZE); /* memory pool: Read-Write for user tasks */ usr_pool_ptr = _usr_mem_alloc(sizeof(LWMEM_POOL_STRUCT)); usr_pool_start = _mem_alloc(1024); usr_pool_id = _lwmem_create_pool(usr_pool_ptr, usr_pool_start, 1024); _mem_set_pool_access(usr_pool_id, POOL_USER_RW_ACCESS); /* create the user "main" task, whcih then creates the others */ _task_create(0, USR_MAIN_TASK, USR_TASK_CNT); /* receive messages from user tasks and print */ while (1) { _lwmsgq_receive((pointer)que, msg, LWMSGQ_RECEIVE_BLOCK_ON_EMPTY, 0, 0); printf(" %c \n", msg[0]); } }
void mqx_initialize_heap(void) { /** Definiton of heap for RealView compiler */ char *__heap_addr = (char *)__get_heap_base(); int __heap_size = __get_heap_limit() - __get_heap_base(); LWMEM_POOL_STRUCT * pool_ptr; void * start_addr; pool_ptr = (LWMEM_POOL_STRUCT *) __heap_addr; /* Set default lwmem pool */ (void)_lwmem_set_default_pool(pool_ptr); start_addr = (void *)((char *) __heap_addr + sizeof(LWMEM_POOL_STRUCT)); _lwmem_create_pool(pool_ptr, start_addr, (_mem_size)__heap_size); }
void mqx_initialize_heap(void) { /** Definiton of heap for GCC ARM compiler * Extern symbols defined in linker command file */ extern char __heap_addr[]; extern char __heap_size[]; LWMEM_POOL_STRUCT * pool_ptr; void * start_addr; pool_ptr = (LWMEM_POOL_STRUCT *) __heap_addr; /* Set default lwmem pool */ (void)_lwmem_set_default_pool(pool_ptr); start_addr = (void *)((char *) __heap_addr + sizeof(LWMEM_POOL_STRUCT)); _lwmem_create_pool(pool_ptr, start_addr, (_mem_size)__heap_size); }
uint_32 _bsp_enable_card ( void ) { KERNEL_DATA_STRUCT_PTR kernel_data; uint_32 result; _GET_KERNEL_DATA(kernel_data); _mqx_set_cpu_type(MQX_CPU); #if MQX_EXIT_ENABLED /* Set the bsp exit handler, called by _mqx_exit */ _mqx_set_exit_handler(_bsp_exit_handler); #endif /* Memory splitter - prevent accessing both ram banks in one instruction */ _mem_alloc_at(0, (void*)0x20000000); /* === Debugging is not allowed from here === */ /* Initialize the interrupt handling */ result = _psp_int_init(BSP_FIRST_INTERRUPT_VECTOR_USED, BSP_LAST_INTERRUPT_VECTOR_USED); /* === Debugging may now resume === */ if (result != MQX_OK) { return result; } /* set possible new interrupt vector table - if MQX_ROM_VECTORS = 0 switch to ram interrupt table which was initialized in _psp_int_init) */ (void)_int_set_vector_table(BSP_INTERRUPT_VECTOR_TABLE); /* Store timer interrupt vector for debugger */ _time_set_timer_vector(BSP_TIMER_INTERRUPT_VECTOR); /* Install Timer ISR. */ if (_int_install_isr(BSP_TIMER_INTERRUPT_VECTOR, (void (_CODE_PTR_)(pointer))_bsp_systick, NULL) == NULL) { return MQX_TIMER_ISR_INSTALL_FAIL; } /** bsp low level internal initialization. ***/ _bsp_low_level_init(); /* System timer initialization */ systick_init(); /* MCG initialization and internal oscillators trimming */ if (CM_ERR_OK != _bsp_set_clock_configuration(BSP_CLOCK_CONFIGURATION_AUTOTRIM)) { return MQX_TIMER_ISR_INSTALL_FAIL; } if (CM_ERR_OK != _bsp_osc_autotrim()) { return MQX_TIMER_ISR_INSTALL_FAIL; } /* Switch to startup clock configuration */ if (CM_ERR_OK != _bsp_set_clock_configuration(BSP_CLOCK_CONFIGURATION_STARTUP)) { return MQX_TIMER_ISR_INSTALL_FAIL; } /* Initialize the system ticks */ _GET_KERNEL_DATA(kernel_data); kernel_data->TIMER_HW_REFERENCE = (BSP_SYSTEM_CLOCK / BSP_ALARM_FREQUENCY); _time_set_ticks_per_sec(BSP_ALARM_FREQUENCY); _time_set_hwticks_per_tick(kernel_data->TIMER_HW_REFERENCE); _time_set_hwtick_function(_bsp_get_hwticks, (pointer)NULL); #if MQX_ENABLE_USER_MODE _kinetis_mpu_init(); // supervisor full access, user no access for whole memory _kinetis_mpu_add_region(0, ((uchar_ptr)kernel_data->INIT.START_OF_USER_NO_MEMORY) - 1, \ MPU_WORD_M3SM(MPU_SM_RWX) | MPU_WORD_M3UM(MPU_UM_R | MPU_UM_X) | \ MPU_WORD_M2SM(MPU_SM_RWX) | MPU_WORD_M2UM(MPU_UM_R | MPU_UM_X) | \ MPU_WORD_M1SM(MPU_SM_RWX) | MPU_WORD_M1UM(MPU_UM_R | MPU_UM_X) | \ MPU_WORD_M0SM(MPU_SM_RWX) | MPU_WORD_M0UM(MPU_UM_R | MPU_UM_X)); _kinetis_mpu_add_region(((uchar_ptr)kernel_data->INIT.END_OF_USER_NO_MEMORY), (uchar_ptr)0xffffffff, \ MPU_WORD_M3SM(MPU_SM_RWX) | MPU_WORD_M3UM(MPU_UM_R | MPU_UM_X) | \ MPU_WORD_M2SM(MPU_SM_RWX) | MPU_WORD_M2UM(MPU_UM_R | MPU_UM_X) | \ MPU_WORD_M1SM(MPU_SM_RWX) | MPU_WORD_M1UM(MPU_UM_R | MPU_UM_X) | \ MPU_WORD_M0SM(MPU_SM_RWX) | MPU_WORD_M0UM(MPU_UM_R | MPU_UM_X)); // set access for user memory area #if MQX_DEFAULT_USER_ACCESS_RW // user .data RW _kinetis_mpu_add_region(kernel_data->INIT.START_OF_USER_DEFAULT_MEMORY, ((uchar_ptr)kernel_data->INIT.END_OF_USER_DEFAULT_MEMORY) - 1, \ MPU_WORD_M1SM(MPU_SM_RWX) | MPU_WORD_M1UM(MPU_UM_R | MPU_UM_W) | \ MPU_WORD_M0SM(MPU_SM_RWX) | MPU_WORD_M0UM(MPU_UM_R | MPU_UM_W)); #else // user RO - this is by default // user .data RO /*_kinetis_mpu_add_region(kernel_data->INIT.START_OF_KERNEL_AREA, kernel_data->INIT.END_OF_KERNEL_AREA, \ MPU_WORD_M1SM(MPU_SM_RWX) | MPU_WORD_M1UM(MPU_UM_R) | \ MPU_WORD_M0SM(MPU_SM_RWX) | MPU_WORD_M0UM(MPU_UM_R)); */ #endif // MQX_DEFAULT_USER_ACCESS_RW // set access for user memory area if (0 == kernel_data->INIT.END_OF_USER_HEAP) { // create user heap automaticaly, we have specified only size of heap (end of heap is zero, start of heap mean size) LWMEM_POOL_STRUCT_PTR lwmem_pool_ptr; uchar_ptr start; //start = _lwmem_alloc((char*)kernel_data->INIT.END_OF_USER_HEAP - (char*)kernel_data->INIT.START_OF_USER_HEAP + sizeof(LWMEM_POOL_STRUCT)); start = _lwmem_alloc((uint_32)kernel_data->INIT.START_OF_USER_HEAP + sizeof(LWMEM_POOL_STRUCT)); lwmem_pool_ptr = (LWMEM_POOL_STRUCT_PTR)start; start = (pointer)((uchar_ptr)start + sizeof(LWMEM_POOL_STRUCT)); _lwmem_create_pool(lwmem_pool_ptr, start, (uint_32)kernel_data->INIT.START_OF_USER_HEAP); _mem_set_pool_access(lwmem_pool_ptr, POOL_USER_RW_ACCESS); kernel_data->KD_USER_POOL = lwmem_pool_ptr; } else { // manual user heap definition _kinetis_mpu_add_region(kernel_data->INIT.START_OF_USER_HEAP, ((uchar_ptr)kernel_data->INIT.END_OF_USER_HEAP) - 1, \ MPU_WORD_M1SM(MPU_SM_RWX) | MPU_WORD_M1UM(MPU_UM_R | MPU_UM_W) | \ MPU_WORD_M0SM(MPU_SM_RWX) | MPU_WORD_M0UM(MPU_UM_R | MPU_UM_W)); } // set access for user read-write memory area if (kernel_data->INIT.START_OF_USER_RW_MEMORY < kernel_data->INIT.END_OF_USER_RW_MEMORY) { _kinetis_mpu_add_region(kernel_data->INIT.START_OF_USER_RW_MEMORY, ((uchar_ptr)kernel_data->INIT.END_OF_USER_RW_MEMORY) - 1, \ MPU_WORD_M1SM(MPU_SM_RWX) | MPU_WORD_M1UM(MPU_UM_R | MPU_UM_W) | \ MPU_WORD_M0SM(MPU_SM_RWX) | MPU_WORD_M0UM(MPU_UM_R | MPU_UM_W)); } // set access for user read-only memory area if (kernel_data->INIT.START_OF_USER_RO_MEMORY < kernel_data->INIT.END_OF_USER_RO_MEMORY) { _kinetis_mpu_add_region(kernel_data->INIT.START_OF_USER_RO_MEMORY, ((uchar_ptr)kernel_data->INIT.END_OF_USER_RO_MEMORY) - 1, \ MPU_WORD_M1SM(MPU_SM_RWX) | MPU_WORD_M1UM(MPU_UM_R) | \ MPU_WORD_M0SM(MPU_SM_RWX) | MPU_WORD_M0UM(MPU_UM_R)); } // set access for user no access memory area if (kernel_data->INIT.START_OF_USER_NO_MEMORY < kernel_data->INIT.END_OF_USER_NO_MEMORY) { _kinetis_mpu_add_region(kernel_data->INIT.START_OF_USER_NO_MEMORY, ((uchar_ptr)kernel_data->INIT.END_OF_USER_NO_MEMORY) - 1, \ MPU_WORD_M1SM(MPU_SM_RWX) | MPU_WORD_M1UM(0) | \ MPU_WORD_M0SM(MPU_SM_RWX) | MPU_WORD_M0UM(0)); } _kinetis_mpu_enable(); #else _kinetis_mpu_disable(); #endif /* MQX_ENABLE_USER_MODE */ /* Install low power support */ #if MQX_ENABLE_LOW_POWER MC_PMPROT = MC_PMPROT_AVLP_MASK | MC_PMPROT_ALLS_MASK; // allow VLPx, LLS, disallow VLLSx _lpm_install (LPM_CPU_OPERATION_MODES, LPM_OPERATION_MODE_RUN); #endif /* MQX_ENABLE_LOW_POWER */ #if BSPCFG_ENABLE_IO_SUBSYSTEM /*------------------------------------------------------------------------*/ /* ** Initialize the I/O Sub-system */ result = _io_init(); if (result != MQX_OK) { return result; } /* Endif */ /* Initialize RTC and MQX time */ #if BSPCFG_ENABLE_RTCDEV if (MQX_OK == _bsp_rtc_io_init()) { _rtc_init (RTC_INIT_FLAG_ENABLE); _rtc_sync_with_mqx (TRUE); } #endif /* Install device drivers */ #if BSPCFG_ENABLE_TTYA _kuart_polled_install("ttya:", &_bsp_sci0_init, _bsp_sci0_init.QUEUE_SIZE); #endif #if BSPCFG_ENABLE_ITTYA _kuart_int_install("ittya:", &_bsp_sci0_init, _bsp_sci0_init.QUEUE_SIZE); #endif #if BSPCFG_ENABLE_TTYB _kuart_polled_install("ttyb:", &_bsp_sci1_init, _bsp_sci1_init.QUEUE_SIZE); #endif #if BSPCFG_ENABLE_ITTYB _kuart_int_install("ittyb:", &_bsp_sci1_init, _bsp_sci1_init.QUEUE_SIZE); #endif #if BSPCFG_ENABLE_TTYC _kuart_polled_install("ttyc:", &_bsp_sci2_init, _bsp_sci2_init.QUEUE_SIZE); #endif #if BSPCFG_ENABLE_ITTYC _kuart_int_install("ittyc:", &_bsp_sci2_init, _bsp_sci2_init.QUEUE_SIZE); #endif #if BSPCFG_ENABLE_TTYD _kuart_polled_install("ttyd:", &_bsp_sci3_init, _bsp_sci3_init.QUEUE_SIZE); #endif #if BSPCFG_ENABLE_ITTYD _kuart_int_install("ittyd:", &_bsp_sci3_init, _bsp_sci3_init.QUEUE_SIZE); #endif #if BSPCFG_ENABLE_TTYE _kuart_polled_install("ttye:", &_bsp_sci4_init, _bsp_sci4_init.QUEUE_SIZE); #endif #if BSPCFG_ENABLE_ITTYE _kuart_int_install("ittye:", &_bsp_sci4_init, _bsp_sci4_init.QUEUE_SIZE); #endif #if BSPCFG_ENABLE_TTYF _kuart_polled_install("ttyf:", &_bsp_sci5_init, _bsp_sci5_init.QUEUE_SIZE); #endif #if BSPCFG_ENABLE_ITTYF _kuart_int_install("ittyf:", &_bsp_sci5_init, _bsp_sci5_init.QUEUE_SIZE); #endif #if BSPCFG_ENABLE_I2C0 _ki2c_polled_install("i2c0:", &_bsp_i2c0_init); #endif #if BSPCFG_ENABLE_I2C1 _ki2c_polled_install("i2c1:", &_bsp_i2c1_init); #endif #if BSPCFG_ENABLE_II2C0 _ki2c_int_install("ii2c0:", &_bsp_i2c0_init); #endif #if BSPCFG_ENABLE_II2C1 _ki2c_int_install("ii2c1:", &_bsp_i2c1_init); #endif #if BSPCFG_ENABLE_SPI0 _dspi_polled_install("spi0:", &_bsp_dspi0_init); #endif #if BSPCFG_ENABLE_ISPI0 _dspi_dma_install("ispi0:", &_bsp_dspi0_init); #endif #if BSPCFG_ENABLE_SPI1 _dspi_polled_install("spi1:", &_bsp_dspi1_init); #endif #if BSPCFG_ENABLE_ISPI1 _dspi_dma_install("ispi1:", &_bsp_dspi1_init); #endif #if BSPCFG_ENABLE_SPI2 _dspi_polled_install("spi2:", &_bsp_dspi2_init); #endif #if BSPCFG_ENABLE_ISPI2 _dspi_dma_install("ispi2:", &_bsp_dspi2_init); #endif /* Install the GPIO driver */ #if BSPCFG_ENABLE_GPIODEV _io_gpio_install("gpio:"); #endif #if BSPCFG_ENABLE_ADC0 _io_adc_install("adc0:", (pointer) &_bsp_adc0_init); #endif #if BSPCFG_ENABLE_ADC1 _io_adc_install("adc1:", (pointer) &_bsp_adc1_init); #endif #if BSPCFG_ENABLE_ESDHC _esdhc_install ("esdhc:", &_bsp_esdhc0_init); #endif /* Install the PCCard Flash drivers */ #if BSPCFG_ENABLE_PCFLASH _io_pccardflexbus_install("pccarda:", (PCCARDFLEXBUS_INIT_STRUCT _PTR_) &_bsp_cfcard_init); _io_apcflash_install("pcflasha:"); #endif #if BSPCFG_ENABLE_FLASHX _io_flashx_install("flashx:", &_bsp_flashx_init); #endif #if BSPCFG_ENABLE_IODEBUG _io_debug_install("iodebug:", &_bsp_iodebug_init); #endif #if BSPCFG_ENABLE_II2S0 _ki2s_int_install("ii2s0:", &_bsp_i2s0_init); #endif /* Initialize the default serial I/O */ _io_serial_default_init(); #endif // BSPCFG_ENABLE_IO_SUBSYSTEM return MQX_OK; }
/*! * \brief MQX API handler for usermode - part of wrapper around standard MQX API * which require privilege mode. * * \param[in] api_no API number - number of wrapped function * \param[in] params generic parameter - direct use with called MQX API fn * * \return uint32_t return of called function */ uint32_t _mqx_api_call_handler ( // [IN] API number - number of wrapped function MQX_API_NUMBER_ENUM api_no, // [IN] generic parameter - direct use with called MQX API fn MQX_API_CALL_PARAMS_PTR params ) { int32_t res = -1; uint32_t param0 = params->param0; uint32_t param1 = params->param1; uint32_t param2 = params->param2; uint32_t param3 = params->param3; uint32_t param4 = params->param4; switch (api_no) { // _lwsem case MQX_API_LWSEM_POLL: if (MQX_OK == (res = _lwsem_usr_check((LWSEM_STRUCT_PTR)param0))) res = (uint32_t)_lwsem_poll((LWSEM_STRUCT_PTR)param0); break; case MQX_API_LWSEM_POST: if (MQX_OK == (res = _lwsem_usr_check((LWSEM_STRUCT_PTR)param0))) res = _lwsem_post((LWSEM_STRUCT_PTR)param0); break; case MQX_API_LWSEM_WAIT: if (MQX_OK == (res = _lwsem_usr_check((LWSEM_STRUCT_PTR)param0))) res = _lwsem_wait((LWSEM_STRUCT_PTR)param0); break; case MQX_API_LWSEM_CREATE: res = _lwsem_create_internal((LWSEM_STRUCT_PTR)param0, (_mqx_int)param1, (bool)param2, TRUE); break; #if MQX_HAS_TICK case MQX_API_LWSEM_WAIT_FOR: if (MQX_OK == (res = _lwsem_usr_check((LWSEM_STRUCT_PTR)param0)) && (!param1 || _psp_mem_check_access(param1, sizeof(MQX_TICK_STRUCT), MPU_UM_RW))) res = _lwsem_wait_for((LWSEM_STRUCT_PTR)param0, (MQX_TICK_STRUCT_PTR)param1); break; case MQX_API_LWSEM_WAIT_TICKS: if (MQX_OK == (res = _lwsem_usr_check((LWSEM_STRUCT_PTR)param0))) res = _lwsem_wait_ticks((LWSEM_STRUCT_PTR)param0, (_mqx_uint)param1); break; case MQX_API_LWSEM_WAIT_UNTIL: if (MQX_OK == (res = _lwsem_usr_check((LWSEM_STRUCT_PTR)param0)) && (!param1 || _psp_mem_check_access(param1, sizeof(MQX_TICK_STRUCT), MPU_UM_RW))) res = _lwsem_wait_until((LWSEM_STRUCT_PTR)param0, (MQX_TICK_STRUCT_PTR)param1); break; case MQX_API_LWSEM_DESTROY: if (MQX_OK == (res = _lwsem_usr_check((LWSEM_STRUCT_PTR)param0))) { res = _lwsem_destroy_internal((LWSEM_STRUCT_PTR)param0, TRUE); } break; #endif // MQX_HAS_TICK // _lwevent #if MQX_USE_LWEVENTS case MQX_API_LWEVENT_CLEAR: if (MQX_OK == (res = _lwevent_usr_check((LWEVENT_STRUCT_PTR)param0))) res = _lwevent_clear((LWEVENT_STRUCT_PTR)param0, (_mqx_uint)param1); break; case MQX_API_LWEVENT_SET: if (MQX_OK == (res = _lwevent_usr_check((LWEVENT_STRUCT_PTR)param0))) res = _lwevent_set((LWEVENT_STRUCT_PTR)param0, (_mqx_uint)param1); break; case MQX_API_LWEVENT_SET_AUTO_CLEAR: if (MQX_OK == (res = _lwevent_usr_check((LWEVENT_STRUCT_PTR)param0))) res = _lwevent_set_auto_clear((LWEVENT_STRUCT_PTR)param0, (_mqx_uint)param1); break; case MQX_API_LWEVENT_WAIT_FOR: if (MQX_OK == (res = _lwevent_usr_check((LWEVENT_STRUCT_PTR)param0)) && \ (!param3 || _psp_mem_check_access(param3, sizeof(MQX_TICK_STRUCT), MPU_UM_RW))) { res = _lwevent_wait_for((LWEVENT_STRUCT_PTR)param0, (_mqx_uint)param1, (bool)param2, (MQX_TICK_STRUCT_PTR)param3); } break; case MQX_API_LWEVENT_WAIT_FOR_TICKS: if (MQX_OK == (res = _lwevent_usr_check((LWEVENT_STRUCT_PTR)param0))) { res = _lwevent_wait_ticks((LWEVENT_STRUCT_PTR)param0, (_mqx_uint)param1, (bool)param2, (_mqx_uint)param3); } break; case MQX_API_LWEVENT_WAIT_UNTIL: if (MQX_OK == (res = _lwevent_usr_check((LWEVENT_STRUCT_PTR)param0)) && \ (!param3 || _psp_mem_check_access(param3, sizeof(MQX_TICK_STRUCT), MPU_UM_RW))) { res = _lwevent_wait_until((LWEVENT_STRUCT_PTR)param0, (_mqx_uint)param1, (bool)param2, (MQX_TICK_STRUCT_PTR)param3); } break; case MQX_API_LWEVENT_GET_SIGNALLED: res = _lwevent_get_signalled(); break; case MQX_API_LWEVENT_CREATE: res = _lwevent_create_internal((LWEVENT_STRUCT_PTR)param0, (_mqx_uint)param1, TRUE); break; case MQX_API_LWEVENT_DESTROY: if (MQX_OK == (res = _lwevent_usr_check((LWEVENT_STRUCT_PTR)param0))) { res = _lwevent_destroy_internal((LWEVENT_STRUCT_PTR)param0, TRUE); } break; #endif #if MQX_USE_LWMSGQ case MQX_API_LWMSGQ_INIT: res = _lwmsgq_init_internal((void *)param0, (_mqx_uint)param1, (_mqx_uint)param2, TRUE); break; case MQX_API_LWMSGQ_RECEIVE: if (MQX_OK == (res = _lwmsgq_usr_check((LWMSGQ_STRUCT_PTR)param0)) && \ _psp_mem_check_access(param1, ((LWMSGQ_STRUCT_PTR)param0)->MSG_SIZE, MPU_UM_RW) && \ (!param4 || _psp_mem_check_access(param4, sizeof(MQX_TICK_STRUCT), MPU_UM_RW))) res = _lwmsgq_receive((void *)param0, (_mqx_max_type_ptr)param1, (_mqx_uint)param2, (_mqx_uint)param3, (MQX_TICK_STRUCT_PTR)param4); break; case MQX_API_LWMSGQ_SEND: if (MQX_OK == (res = _lwmsgq_usr_check((LWMSGQ_STRUCT_PTR)param0)) && \ _psp_mem_check_access(param1, ((LWMSGQ_STRUCT_PTR)param0)->MSG_SIZE, MPU_UM_RW)) res = _lwmsgq_send((void *)param0, (_mqx_max_type_ptr)param1, (_mqx_uint)param2); break; #endif // MQX_USE_LWMSGQ case MQX_API_TASK_CREATE: res = _task_create_internal((_processor_number)param0, (_mqx_uint)param1, (uint32_t)param2, TRUE); break; case MQX_API_TASK_DESTROY: res = _task_destroy_internal((_task_id)param0, TRUE); break; case MQX_API_TASK_ABORT: res = _task_abort_internal((_task_id)param0, TRUE); break; case MQX_API_TASK_READY: _task_ready((void *)param0); res = MQX_OK; // irelevant, function is without return value break; case MQX_API_TASK_SET_ERROR: res = _task_set_error((_mqx_uint)param0); break; case MQX_API_TASK_GET_TD: res = (uint32_t)_task_get_td((_task_id)param0); break; #if MQX_USE_LWMEM case MQX_API_LWMEM_ALLOC: res = (uint32_t)_usr_lwmem_alloc_internal((_mem_size)param0); break; case MQX_API_LWMEM_ALLOC_FROM: if (_psp_mem_check_access(param0, sizeof(LWMEM_POOL_STRUCT), MPU_UM_RW) && \ _psp_mem_check_access((uint32_t)(((LWMEM_POOL_STRUCT_PTR)param0)->POOL_ALLOC_START_PTR), (char*)(((LWMEM_POOL_STRUCT_PTR)param0)->POOL_ALLOC_END_PTR) - (char*)(((LWMEM_POOL_STRUCT_PTR)param0)->POOL_ALLOC_START_PTR), MPU_UM_RW)) res = (uint32_t)_lwmem_alloc_from((_lwmem_pool_id)param0, (_mem_size)param1); else res = 0; // NULL, allocation failed break; case MQX_API_LWMEM_FREE: if (_psp_mem_check_access(param0, 4, MPU_UM_RW)) res = _lwmem_free((void *)param0); break; case MQX_API_LWMEM_CREATE_POOL:\ if (_psp_mem_check_access(param0, sizeof(LWMEM_POOL_STRUCT), MPU_UM_RW) && \ _psp_mem_check_access(param1, param2, MPU_UM_RW)) res = (uint32_t)_lwmem_create_pool((LWMEM_POOL_STRUCT_PTR)param0, (void *)param1, (_mem_size)param2); break; case MQX_API_LWMEM_REALLOC: if (_psp_mem_check_access(param0, 4, MPU_UM_RW)) res = (uint32_t)_lwmem_realloc((void *)param0,(_mem_size)param1); break; #endif // MQX_USE_LWMEM // _time case MQX_API_TIME_DELAY: _time_delay(param0); res = MQX_OK; // irelevant, function is without return value break; #if MQX_HAS_TICK case MQX_API_TIME_DELAY_TICKS: _time_delay_ticks(param0); res = MQX_OK; // irelevant, function is without return value break; case MQX_API_TIME_GET_ELAPSED_TICKS: if (_psp_mem_check_access(param0, sizeof(MQX_TICK_STRUCT), MPU_UM_RW)) { _time_get_elapsed_ticks((MQX_TICK_STRUCT_PTR)param0); res = MQX_OK; // irelevant, function is without return value } else { _task_set_error(MQX_ACCESS_ERROR); } break; #endif // MQX_HAS_TICK default: while (1); } return res; }
/*! * \brief Initializes MQXLite on the processor. * * The function does the following: * \n - Initializes kernel data. * \n - Creates the interrupt stack. * \n - Creates the ready queues. * \n - Creates a lightweight semaphore for task creation/destruction. * \n - Initializes interrupts. * \n - Initializes system timer. * * \param[in] mqx_init Pointer to the MQXLITE initialization structure for the * processor. * * \return MQX_OK * \return Initialization error code * * \warning Must be called exactly once per processor. * * \see _mqxlite * \see _mqx_exit * \see MQXLITE_INITIALIZATION_STRUCT */ _mqx_uint _mqxlite_init ( MQXLITE_INITIALIZATION_STRUCT const * mqx_init ) { /* Body */ KERNEL_DATA_STRUCT_PTR kernel_data; pointer stack_ptr; _mqx_uint result = MQX_OK; /* * The kernel data structure starts at the start of kernel memory, * as specified in the initialization structure. Make sure address * specified is aligned */ kernel_data = (KERNEL_DATA_STRUCT_PTR) (mqx_init->START_OF_KERNEL_MEMORY); /* Set the global pointer to the kernel data structure */ _SET_KERNEL_DATA(kernel_data); /* The following assignments are done to force the linker to include * the symbols, which are required by TAD. * Note that we should use address of the variable so it is not optimized * as direct constant assignment when optimization level is high. * Note that counter will be immediately reset to zero on the subsequent * _mem_zero call. */ { MQX_INITIALIZATION_STRUCT * MQX_init_struct_ptr; *(volatile pointer*) kernel_data = (pointer) & _mqx_version_number; *(volatile pointer*) kernel_data = (pointer) & _mqx_vendor; *(volatile pointer*) kernel_data = (pointer) & _mqx_path; *(volatile pointer*) kernel_data = (pointer) & _mqxlite_version_number; *(volatile pointer*) kernel_data = (pointer) & MQX_init_struct_ptr; } /* Initialize the kernel data to zero. */ _mem_zero((pointer) kernel_data, (_mem_size) sizeof(KERNEL_DATA_STRUCT)); #if MQX_CHECK_ERRORS && MQX_VERIFY_KERNEL_DATA /* Verify that kernel data can be read and written correctly without * errors. This is necessary during BSP development to validate the * DRAM controller is initialized properly. */ if (PSP_KERNEL_DATA_VERIFY_ENABLE) { /* This memory check is dangerous, because can destroy boot stack * stack which is used !!! -> MQX will failed ! * Set PSP_KERNEL_DATA_VERIFY_ENABLE to 1 * only if your boot stack is out of MQX memory heap */ result = _mem_verify((uchar_ptr)kernel_data + sizeof(KERNEL_DATA_STRUCT), mqx_init->END_OF_KERNEL_MEMORY); if ( result != MQX_OK ) { return (result); /* RETURN TO USER */ } } #endif /* MQX_CHECK_ERRORS && MQX_VERIFY_KERNEL_DATA */ /* Copy the MQX initialization structure into kernel data. */ kernel_data->INIT = *mqx_init; /* init kernel data structures */ _mqx_init_kernel_data_internal(); #if MQX_USE_LWMEM == 1 /** * Initialize lightweight memory pool for dynamic memory allocation */ { /* Extern symbols defined in linker command file */ extern char __heap_addr[]; extern char __heap_size[]; KERNEL_DATA_STRUCT * kernel_data; LWMEM_POOL_STRUCT * pool_ptr; void * start_addr; _GET_KERNEL_DATA(kernel_data); pool_ptr = (LWMEM_POOL_STRUCT *) __heap_addr; kernel_data->KERNEL_LWMEM_POOL = pool_ptr; start_addr = (void *)((char *) __heap_addr + sizeof(LWMEM_POOL_STRUCT)); _lwmem_create_pool(pool_ptr, start_addr, (_mem_size)__heap_size); } #endif #if MQX_USE_INTERRUPTS /* Now obtain the interrupt stack */ if (kernel_data->INIT.INTERRUPT_STACK_LOCATION) { stack_ptr = kernel_data->INIT.INTERRUPT_STACK_LOCATION; result = kernel_data->INIT.INTERRUPT_STACK_SIZE; } else { return (MQX_INVALID_PARAMETER); } /* Endif */ #if MQX_MONITOR_STACK _task_fill_stack_internal((_mqx_uint_ptr)stack_ptr, result); #endif kernel_data->INTERRUPT_STACK_PTR = _GET_STACK_BASE(stack_ptr, result); #endif /* MQX_USE_INTERRUPTS */ #if MQX_USE_IDLE_TASK == 0 { /* * Set the stack for the system TD, in case the idle task gets blocked * by an exception or if idle task is not used. */ TD_STRUCT_PTR td_ptr; uchar_ptr stack_base_ptr; stack_base_ptr = (uchar_ptr) _GET_STACK_BASE(mqx_system_stack, PSP_MINSTACKSIZE); td_ptr = SYSTEM_TD_PTR(kernel_data); td_ptr->STACK_PTR = (pointer)(stack_base_ptr - sizeof(PSP_STACK_START_STRUCT)); td_ptr->STACK_BASE = stack_base_ptr; #if MQX_TD_HAS_STACK_LIMIT td_ptr->STACK_LIMIT = _GET_STACK_LIMIT(mqx_system_stack, PSP_MINSTACKSIZE); #endif _mqx_system_stack = td_ptr->STACK_PTR; } #endif /* MQX_USE_IDLE_TASK */ /* Build the MQX ready to run queues */ result = _psp_init_readyqs(); #if MQX_CHECK_MEMORY_ALLOCATION_ERRORS if ( result != MQX_OK ) { return (result); /* RETURN TO USER */ } /* Endif */ #endif #if MQX_USE_COMPONENTS /* Create a light wait semaphore for component creation */ _lwsem_create((LWSEM_STRUCT_PTR)&kernel_data->COMPONENT_CREATE_LWSEM, 1); #endif /* Create a light wait semaphore for task creation/destruction creation */ _lwsem_create((LWSEM_STRUCT_PTR) & kernel_data->TASK_CREATE_LWSEM, 1); /* Set the CPU type */ _mqx_set_cpu_type(MQX_CPU); result = _psp_int_init(FIRST_INTERRUPT_VECTOR_USED, LAST_INTERRUPT_VECTOR_USED); if (result != MQX_OK) { return(result); /* RETURN TO USER */ } /* set possible new interrupt vector table * if MQX_ROM_VECTORS = 0 switch to ram interrupt table which * was initialized in _psp_int_init) */ _int_set_vector_table((uint32_t)(&__vect_table)); /* * Initialize System Timer and Ticks parameters in kernel_data structure */ system_timer_init(NULL); return MQX_OK; /* To satisfy lint */ } /* Endbody */