Error[Pe020]: identifier is undefined in vector table for RTOS-based ADC Interrupt

I’m doing a training program for embedded development, and right now I’m working on setting up an ADC interrupt in an RTOS environment in IAR Embedded Workbench.

I’m running into a problem when I try to link the ADC interrupt to the AdcIsr function within the interrupt vector table. The instructions for the assignment says to replace (CPU_FNCT_VOID)BSP_IntHandler_102 on line 102, with (CPU_FNCT_VOID)AdcIsr

Here is the code for interrupts.c, which contains the interrupt vector table and their interrupt handlers:

#include  <bsp_cfg.h>
#include  <cpu.h>
#include  <os.h>
#include <stdint.h>
#include  <cpu_core.h>
#include  <lib_def.h>
#include  <bsp_int_vect_tbl.h>
#include "adc.h"

/*
*********************************************************************************************************
*                                       INTERRUPT VECTOR TABLE
*
* Note(s): 1) Could be in RAM if BSP_CFG_INT_VECT_RAM_EN is set to 1 in 'bsp_cfg.h'
*          2) In either case BSP_IntVectSet() must becalled to boint to BSP_IntVectTbl[]
*
*********************************************************************************************************
*/

#if     BSP_CFG_INT_VECT_TBL_RAM_EN > 0u
static  CPU_FNCT_VOID  BSP_IntVectTbl[] =
#else
const   CPU_FNCT_VOID  BSP_IntVectTbl[] =
#endif
{
    (CPU_FNCT_VOID)BSP_IntHandler_000,              /*  00 */
    (CPU_FNCT_VOID)BSP_IntHandler_001,              /*  01 */
    (CPU_FNCT_VOID)BSP_IntHandler_002,              /*  02 */
    (CPU_FNCT_VOID)BSP_IntHandler_003,              /*  03 */
    // ... other interrupt handlers ...
    (CPU_FNCT_VOID)AdcIsr,                          /* 102 */
    // ... other interrupt handlers ...
};

Here is my header file:

#ifndef _ADC_H
#define _ADC_H

void  adc_task (void * p_arg);

#endif /* _ADC_H */

If relevant, here is my C code for the ADC:

#include <assert.h>
#include <stdint.h>             
#include <stdio.h>

#include "os.h"
#include "iorx63n.h"

#include "adc.h"
#include  <bsp_glcd.h>


// Message Queue for ISR->Task Communication
static OS_Q  g_adc_q;


#define ADC_SOURCE_VR1      2

#define ADC_INTERRUPT_AFTER_SCAN    0x10
#define ADC_START                   0x80

#define BIT(n)              (1 << (n))


// NOTE: Refer to p. 1,698 to 1,727  of Processor_UsersManual_Hardware.pdf
typedef struct
{
  uint8_t           control;                      // Offset 0x00
  uint8_t  const    _unused1[3];
  uint16_t          channel_select0;              // Offset 0x04
  uint16_t          channel_select1;              // Offset 0x06
  uint16_t          value_addition_mode_select0;  // Offset 0x08
  uint16_t          value_addition_mode_select1;  // Offset 0x0A
  uint8_t           value_addition_count_select;  // Offset 0x0C
  uint8_t  const    _unused2;
  uint16_t          control_extended;             // Offset 0x0E
  uint8_t           start_trigger_select;         // Offset 0x10
  uint8_t  const    _unused3;
  uint16_t          extended_input_control;       // Offset 0x12
  uint8_t  const    _unused4[6];
  uint16_t          temperature_sensor_data;      // Offset 0x1A
  uint16_t          internal_reference_data;      // Offset 0x1C
  uint8_t  const    _unused5[2];
  uint16_t          data[21];                     // Offset 0x20
} adc_t;

adc_t volatile * const p_adc = (adc_t *) 0x00089000;
#define adc     (*p_adc)


/*!
* @brief Configure the ADC hardware to read Potentiometer VR1 and interrupt.
*/
static void adc_config (void)
{
    /* Protection off */
    SYSTEM.PRCR.WORD = 0xA503u;            
    
    /* Cancel the S12AD module clock stop mode */
    MSTP_S12AD = 0;

    /* Protection on */
    SYSTEM.PRCR.WORD = 0xA500u;        

    // Select the 12-bit ADC. In the HW course, this detail is in BSP_Init().
    SYSTEM.MSTPCRA.BIT.MSTPA17 = 0;

    /* Use the AN000 (Potentiometer) pin 
       as an I/O for peripheral functions */
    PORT4.PMR.BYTE = 0x01;

    // Enable A/D interrupts at an appropriate priority, as instructed.
    uint8_t * p_IER = (uint8_t *)0x0008720C;
    uint8_t * p_IPR = (uint8_t *)0x00087366;

    *p_IPR = 9;                         // Set interrupt priority.
    *p_IER |= 0x40;                     // Unmask A/D interrupt.

    // Configure the A/D to perform a single scan and interrupt.
    adc.control = ADC_INTERRUPT_AFTER_SCAN;
    adc.channel_select0 = BIT(ADC_SOURCE_VR1);
}

/*!
*
* @brief: ADC Driver Task
*/
void adc_task (void * p_arg)
{
    OS_ERR     err;

    void *p_msg;
    OS_MSG_SIZE msg_size;
    uint16_t adc_value;
    char p_str[13];

    (void)p_arg;    // NOTE: Silence compiler warning about unused param.

    // Create message queue.
    // NOTE: It's safe to do this here, because the ISR is synchornized to us.
    OSQCreate(&g_adc_q, "ADC Queue", 1, &err);
    assert(OS_ERR_NONE == err); 

    // Configure ADC hardware to read Potentiometer VR1 and interrupt.
    adc_config();
    
    for (;;)    
    {
        // Wait 125 ms.
        OSTimeDlyHMSM(0, 0, 0, 125, OS_OPT_TIME_HMSM_STRICT, &err);
                                            
        // Trigger ADC conversion.
        adc.control |= ADC_START;
            
        // TODO: Wait for message from ISR, then format and display on LCD.;
        p_msg = OSQPend(&g_adc_q, 100, OS_OPT_PEND_BLOCKING, &msg_size, (void *)0, &err);
        adc_value = *(uint16_t*)p_msg;
        sprintf(p_str, "ADC: %4u", adc_value);
        BSP_GraphLCD_String(5, p_str);
    }
}

/*!
*
* @brief ADC Interrupt Handler
*/
void adc_isr (void)
{
    static uint16_t  sample;    // NOTE: Not on the stack; so address is valid.
    OS_ERR           err;

    // Read from the A/D converter and reduce the range from 12-bit to 10-bit.
    sample = adc.data[ADC_SOURCE_VR1] >> 2;
    
    // TODO: Send sample value to ADC task via a message queue
    OSQPost(&g_adc_q, &sample, sizeof(sample), OS_OPT_POST_FIFO + OS_OPT_POST_ALL + OS_OPT_POST_NO_SCHED, &err);
}

The assembly code containing the AdcIsr() function has already been provided to me. The instructions state that no changes need to be made within this file, but I will include it here for context:




    extern     _adc_isr
    extern     _OSIntExit
    extern     _OSIntNestingCtr
    extern     _OSTCBCurPtr

;/*$PAGE*/
;********************************************************************************************************
;                                             AdcIsr()
;********************************************************************************************************

    section .text:CODE:ROOT

    public  _AdcIsr

_AdcIsr:

    PUSHC   FPSW                        ; Save processor registers on the stack
    PUSHM   R1-R15
    MVFACHI R1
    MVFACMI R2
    PUSHM   R1-R2

    MOV.L   #_OSIntNestingCtr, R5       ; Notify uC/OS-III about ISR
    MOV.B   [R5], R3
    ADD     #1, R3
    MOV.B   R3, [R5]

    CMP     #1, R3                      ; if (OSNestingCtr == 1)
    BNE     _AdcIsr1
    MOV.L   #_OSTCBCurPtr, R5           ; Save current task's SP into its TCB
    MOV.L   [R5], R3
    MOV.L   R0, [R3]

_AdcIsr1  MOV.L   #_adc_isr, R5
    JSR     R5

    MOV.L   #_OSIntExit, R5
    JSR     R5                          ; Notify uC/OS-III about end of ISR

    POPM    R1-R2                       ; Restore processor registers from stack
    SHLL    #16, R2
    MVTACLO R2
    MVTACHI R1
    POPM    R1-R15
    POPC    FPSW

    RTE

    end

The error I am getting is:

Error[Pe020]: identifier "AdcIsr" is undefined

Trang chủ Giới thiệu Sinh nhật bé trai Sinh nhật bé gái Tổ chức sự kiện Biểu diễn giải trí Dịch vụ khác Trang trí tiệc cưới Tổ chức khai trương Tư vấn dịch vụ Thư viện ảnh Tin tức - sự kiện Liên hệ Chú hề sinh nhật Trang trí YEAR END PARTY công ty Trang trí tất niên cuối năm Trang trí tất niên xu hướng mới nhất Trang trí sinh nhật bé trai Hải Đăng Trang trí sinh nhật bé Khánh Vân Trang trí sinh nhật Bích Ngân Trang trí sinh nhật bé Thanh Trang Thuê ông già Noel phát quà Biểu diễn xiếc khỉ Xiếc quay đĩa Dịch vụ tổ chức sự kiện 5 sao Thông tin về chúng tôi Dịch vụ sinh nhật bé trai Dịch vụ sinh nhật bé gái Sự kiện trọn gói Các tiết mục giải trí Dịch vụ bổ trợ Tiệc cưới sang trọng Dịch vụ khai trương Tư vấn tổ chức sự kiện Hình ảnh sự kiện Cập nhật tin tức Liên hệ ngay Thuê chú hề chuyên nghiệp Tiệc tất niên cho công ty Trang trí tiệc cuối năm Tiệc tất niên độc đáo Sinh nhật bé Hải Đăng Sinh nhật đáng yêu bé Khánh Vân Sinh nhật sang trọng Bích Ngân Tiệc sinh nhật bé Thanh Trang Dịch vụ ông già Noel Xiếc thú vui nhộn Biểu diễn xiếc quay đĩa Dịch vụ tổ chức tiệc uy tín Khám phá dịch vụ của chúng tôi Tiệc sinh nhật cho bé trai Trang trí tiệc cho bé gái Gói sự kiện chuyên nghiệp Chương trình giải trí hấp dẫn Dịch vụ hỗ trợ sự kiện Trang trí tiệc cưới đẹp Khởi đầu thành công với khai trương Chuyên gia tư vấn sự kiện Xem ảnh các sự kiện đẹp Tin mới về sự kiện Kết nối với đội ngũ chuyên gia Chú hề vui nhộn cho tiệc sinh nhật Ý tưởng tiệc cuối năm Tất niên độc đáo Trang trí tiệc hiện đại Tổ chức sinh nhật cho Hải Đăng Sinh nhật độc quyền Khánh Vân Phong cách tiệc Bích Ngân Trang trí tiệc bé Thanh Trang Thuê dịch vụ ông già Noel chuyên nghiệp Xem xiếc khỉ đặc sắc Xiếc quay đĩa thú vị
Trang chủ Giới thiệu Sinh nhật bé trai Sinh nhật bé gái Tổ chức sự kiện Biểu diễn giải trí Dịch vụ khác Trang trí tiệc cưới Tổ chức khai trương Tư vấn dịch vụ Thư viện ảnh Tin tức - sự kiện Liên hệ Chú hề sinh nhật Trang trí YEAR END PARTY công ty Trang trí tất niên cuối năm Trang trí tất niên xu hướng mới nhất Trang trí sinh nhật bé trai Hải Đăng Trang trí sinh nhật bé Khánh Vân Trang trí sinh nhật Bích Ngân Trang trí sinh nhật bé Thanh Trang Thuê ông già Noel phát quà Biểu diễn xiếc khỉ Xiếc quay đĩa
Thiết kế website Thiết kế website Thiết kế website Cách kháng tài khoản quảng cáo Mua bán Fanpage Facebook Dịch vụ SEO Tổ chức sinh nhật